From 9f18d50ab04d1c67beeca72be9b6b3afaefbb35a Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Sun, 14 Apr 2013 17:16:17 +0200 Subject: [PATCH] config: Fix escapes in string handling --- mopidy/config/types.py | 9 +++++++-- tests/config/types_test.py | 23 ++++++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/mopidy/config/types.py b/mopidy/config/types.py index 1f5c0946..1f57f62c 100644 --- a/mopidy/config/types.py +++ b/mopidy/config/types.py @@ -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): diff --git a/tests/config/types_test.py b/tests/config/types_test.py index 9c12b951..d78db461 100644 --- a/tests/config/types_test.py +++ b/tests/config/types_test.py @@ -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)