diff --git a/Lib/plat-mac/plistlib.py b/Lib/plat-mac/plistlib.py index f73214dd563..49bd5563c94 100644 --- a/Lib/plat-mac/plistlib.py +++ b/Lib/plat-mac/plistlib.py @@ -200,18 +200,21 @@ def _dateToString(d): ) -# Regex to strip all control chars, but for \t \n and \r -_controlStripper = re.compile( +# Regex to find any control chars, except for \t \n and \r +_controlCharPat = re.compile( r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f" r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]") def _escapeAndEncode(text): + m = _controlCharPat.search(text) + if m is not None: + raise ValueError("strings can't contains control characters; " + "use plistlib.Data instead") text = text.replace("\r\n", "\n") # convert DOS line endings text = text.replace("\r", "\n") # convert Mac line endings text = text.replace("&", "&") # escape '&' text = text.replace("<", "<") # escape '<' text = text.replace(">", ">") # escape '>' - text = _controlStripper.sub("?", text) # replace control chars with '?' return text.encode("utf-8") # encode as UTF-8 diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index bf745d3c654..8e8d3e38094 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -165,13 +165,16 @@ class TestPlistlib(unittest.TestCase): self.assertEqual(dict(pl), dict(pl2)) def test_controlcharacters(self): - # chars in the range 0..31 are replaced by '?', except for - # \r, \n and \t since they aren't legal XML characters - testString = "".join([chr(i) for i in range(32)]) - expectedResult = '?????????\t\n??\n??????????????????' - xml = plistlib.writePlistToString(testString) - result = plistlib.readPlistFromString(xml) - self.assertEqual(result, expectedResult) + for i in range(128): + c = chr(i) + testString = "string containing %s" % c + if i >= 32 or c in "\r\n\t": + # \r, \n and \t are the only legal control chars in XML + plistlib.writePlistToString(testString) + else: + self.assertRaises(ValueError, + plistlib.writePlistToString, + testString) def test_nondictroot(self): test1 = "abc"