config: Fix escapes in string handling

This commit is contained in:
Thomas Adamcik 2013-04-14 17:16:17 +02:00
parent 6b89051b5e
commit 9f18d50ab0
2 changed files with 27 additions and 5 deletions

View File

@ -81,7 +81,8 @@ class String(ConfigValue):
"""
def deserialize(self, value):
if not isinstance(value, unicode):
value = value.decode('utf-8')
# TODO: only unescape \n \t and \\?
value = value.decode('string-escape').decode('utf-8')
value = value.strip()
validators.validate_required(value, not self.optional)
validators.validate_choice(value, self.choices)
@ -90,7 +91,11 @@ class String(ConfigValue):
return value
def serialize(self, value):
return value.encode('utf-8').encode('string-escape')
if isinstance(value, unicode):
for char in ('\\', '\n', '\t'): # TODO: more escapes?
value = value.replace(char, char.encode('unicode-escape'))
value = value.encode('utf-8')
return value
class Integer(ConfigValue):

View File

@ -65,7 +65,10 @@ class StringTest(unittest.TestCase):
result = value.deserialize('æøå')
self.assertEqual('æøå', result)
# TODO: add test_deserialize_decodes_string_escapes
def test_deserialize_handles_escapes(self):
value = types.String(optional=True)
result = value.deserialize(b'a\\t\\nb')
self.assertEqual('a\t\nb', result)
def test_deserialize_enforces_choices(self):
value = types.String(choices=['foo', 'bar', 'baz'])
@ -88,9 +91,23 @@ class StringTest(unittest.TestCase):
self.assertRaises(
ValueError, value.deserialize, incorrectly_encoded_bytes)
def test_serialize_string_escapes(self):
def test_serialize_encodes_utf8(self):
value = types.String()
self.assertEqual(r'\r\n\t', value.serialize('\r\n\t'))
result = value.serialize('æøå')
self.assertIsInstance(result, bytes)
self.assertEqual('æøå'.encode('utf-8'), result)
def test_serialize_does_not_encode_bytes(self):
value = types.String()
result = value.serialize('æøå'.encode('utf-8'))
self.assertIsInstance(result, bytes)
self.assertEqual('æøå'.encode('utf-8'), result)
def test_serialize_handles_escapes(self):
value = types.String()
result = value.serialize('a\n\tb')
self.assertIsInstance(result, bytes)
self.assertEqual(r'a\n\tb'.encode('utf-8'), result)
def test_format_masks_secrets(self):
value = types.String(secret=True)