]> granicus.if.org Git - python/commitdiff
On second thought: "Errors should never pass silently", so barf when a
authorJust van Rossum <just@letterror.com>
Fri, 12 Nov 2004 09:36:12 +0000 (09:36 +0000)
committerJust van Rossum <just@letterror.com>
Fri, 12 Nov 2004 09:36:12 +0000 (09:36 +0000)
string contains control chars that are illegal for XML

Lib/plat-mac/plistlib.py
Lib/test/test_plistlib.py

index f73214dd5632cf25153ee66fd259834d255fb450..49bd5563c9406c2c132924611d4b753d860d60fa 100644 (file)
@@ -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("&", "&amp;")       # escape '&'
     text = text.replace("<", "&lt;")        # escape '<'
     text = text.replace(">", "&gt;")        # escape '>'
-    text = _controlStripper.sub("?", text)  # replace control chars with '?'
     return text.encode("utf-8")             # encode as UTF-8
 
 
index bf745d3c654e149a4f4fdfaa6e954e7a94323393..8e8d3e380949b195d02d736622273578246590fe 100644 (file)
@@ -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"