mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-07 08:58:38 +00:00
[Config] Fix loading config with double-quotes in string
If a password or other string contained a double-quote then the config
would fail to be loaded on startup and reset.
This occurred due to fixing a similar issue with curly braces for #3079
in commit 33e9545cd4
and the checking for double-quotes had unforseen
consequences.
To resolve both these issues the code to check for json objects in
config files was simplified and utilises the json module raw_decode
method to ensure the extracted string indexes are json objects.
This commit is contained in:
parent
672e3c42a8
commit
635f6d970d
2 changed files with 42 additions and 27 deletions
|
@ -74,38 +74,33 @@ def prop(func):
|
||||||
return property(doc=func.__doc__, **func())
|
return property(doc=func.__doc__, **func())
|
||||||
|
|
||||||
|
|
||||||
def find_json_objects(s):
|
def find_json_objects(text, decoder=json.JSONDecoder()):
|
||||||
"""Find json objects in a string.
|
"""Find json objects in text.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
s (str): the string to find json objects in
|
text (str): The text to find json objects within.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: A list of tuples containing start and end locations of json
|
list: A list of tuples containing start and end locations of json
|
||||||
objects in string `s`. e.g. [(start, end), ...]
|
objects in the text. e.g. [(start, end), ...]
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
objects = []
|
objects = []
|
||||||
opens = 0
|
offset = 0
|
||||||
start = s.find('{')
|
while True:
|
||||||
offset = start
|
try:
|
||||||
|
start = text.index('{', offset)
|
||||||
|
except ValueError:
|
||||||
|
break
|
||||||
|
|
||||||
if start < 0:
|
try:
|
||||||
return []
|
__, index = decoder.raw_decode(text[start:])
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
quoted = False
|
offset = start + 1
|
||||||
for index, c in enumerate(s[offset:]):
|
else:
|
||||||
if c == '"':
|
offset = start + index
|
||||||
quoted = not quoted
|
objects.append((start, offset))
|
||||||
elif quoted:
|
|
||||||
continue
|
|
||||||
elif c == '{':
|
|
||||||
opens += 1
|
|
||||||
elif c == '}':
|
|
||||||
opens -= 1
|
|
||||||
if opens == 0:
|
|
||||||
objects.append((start, index + offset + 1))
|
|
||||||
start = index + offset + 1
|
|
||||||
|
|
||||||
return objects
|
return objects
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ DEFAULTS = {
|
||||||
'float': 0.435,
|
'float': 0.435,
|
||||||
'bool': True,
|
'bool': True,
|
||||||
'unicode': 'foobar',
|
'unicode': 'foobar',
|
||||||
|
'password': 'abc123*\\[!]?/<>#{@}=|"+$%(^)~',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,6 +96,7 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(config['string'], 'foobar')
|
self.assertEqual(config['string'], 'foobar')
|
||||||
self.assertEqual(config['float'], 0.435)
|
self.assertEqual(config['float'], 0.435)
|
||||||
|
self.assertEqual(config['password'], 'abc123*\\[!]?/<>#{@}=|"+$%(^)~')
|
||||||
|
|
||||||
# Test opening a previous 1.2 config file of just a json object
|
# Test opening a previous 1.2 config file of just a json object
|
||||||
import json
|
import json
|
||||||
|
@ -107,8 +109,8 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
# Test opening a previous 1.2 config file of having the format versions
|
# Test opening a previous 1.2 config file of having the format versions
|
||||||
# as ints
|
# as ints
|
||||||
with open(os.path.join(self.config_dir, 'test.conf'), 'wb') as _file:
|
with open(os.path.join(self.config_dir, 'test.conf'), 'wb') as _file:
|
||||||
_file.write(bytes(1) + b'\n')
|
_file.write(b'1\n')
|
||||||
_file.write(bytes(1) + b'\n')
|
_file.write(b'1\n')
|
||||||
json.dump(DEFAULTS, getwriter('utf8')(_file), **JSON_FORMAT)
|
json.dump(DEFAULTS, getwriter('utf8')(_file), **JSON_FORMAT)
|
||||||
|
|
||||||
check_config()
|
check_config()
|
||||||
|
@ -184,9 +186,27 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
}{
|
}{
|
||||||
"ssl": true,
|
"ssl": true,
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"port": 8115
|
"port": 8115,
|
||||||
"password": "abc{def"
|
"password": "abc{def"
|
||||||
}\n"""
|
}"""
|
||||||
|
|
||||||
|
from deluge.config import find_json_objects
|
||||||
|
|
||||||
|
objects = find_json_objects(s)
|
||||||
|
self.assertEqual(len(objects), 2)
|
||||||
|
|
||||||
|
def test_find_json_objects_double_quote(self):
|
||||||
|
"""Test with string containing double quote"""
|
||||||
|
s = r"""{
|
||||||
|
"file": 1,
|
||||||
|
"format": 1
|
||||||
|
}{
|
||||||
|
"ssl": true,
|
||||||
|
"enabled": false,
|
||||||
|
"port": 8115,
|
||||||
|
"password": "abc\"def"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
from deluge.config import find_json_objects
|
from deluge.config import find_json_objects
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue