]> granicus.if.org Git - python/commitdiff
Issue #16975: Fix error handling bug in the escape-decode bytes decoder.
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 25 Jan 2013 21:31:43 +0000 (23:31 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Fri, 25 Jan 2013 21:31:43 +0000 (23:31 +0200)
Lib/test/test_codecs.py
Misc/NEWS
Objects/bytesobject.c

index 1fa9ee0f5e1fd88dd0d184cd916643ee01ccfad3..2d1b2495938400ee371beadc8ffb4bcfe8670d50 100644 (file)
@@ -805,6 +805,50 @@ class EscapeDecodeTest(unittest.TestCase):
     def test_empty(self):
         self.assertEqual(codecs.escape_decode(""), (b"", 0))
 
+    def test_raw(self):
+        for b in range(256):
+            if b != b'\\'[0]:
+                self.assertEqual(codecs.escape_decode(bytes([b]) + b'0'),
+                                 (bytes([b]) + b'0', 2))
+
+    def test_escape(self):
+        self.assertEqual(codecs.escape_decode(b"[\\\n]"), (b"[]", 4))
+        self.assertEqual(codecs.escape_decode(br'[\"]'), (b'["]', 4))
+        self.assertEqual(codecs.escape_decode(br"[\']"), (b"[']", 4))
+        self.assertEqual(codecs.escape_decode(br"[\\]"), (br"[\]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\a]"), (b"[\x07]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\b]"), (b"[\x08]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\t]"), (b"[\x09]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\n]"), (b"[\x0a]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\v]"), (b"[\x0b]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\f]"), (b"[\x0c]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\r]"), (b"[\x0d]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\7]"), (b"[\x07]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\8]"), (br"[\8]", 4))
+        self.assertEqual(codecs.escape_decode(br"[\78]"), (b"[\x078]", 5))
+        self.assertEqual(codecs.escape_decode(br"[\41]"), (b"[!]", 5))
+        self.assertEqual(codecs.escape_decode(br"[\418]"), (b"[!8]", 6))
+        self.assertEqual(codecs.escape_decode(br"[\101]"), (b"[A]", 6))
+        self.assertEqual(codecs.escape_decode(br"[\1010]"), (b"[A0]", 7))
+        self.assertEqual(codecs.escape_decode(br"[\501]"), (b"[A]", 6))
+        self.assertEqual(codecs.escape_decode(br"[\x41]"), (b"[A]", 6))
+        self.assertEqual(codecs.escape_decode(br"[\X41]"), (br"[\X41]", 6))
+        self.assertEqual(codecs.escape_decode(br"[\x410]"), (b"[A0]", 7))
+        for b in range(256):
+            if b not in b'\n"\'\\abtnvfr01234567x':
+                self.assertEqual(codecs.escape_decode(b'\\' + bytes([b])),
+                                 (b'\\' + bytes([b]), 2))
+
+    def test_errors(self):
+        self.assertRaises(ValueError, codecs.escape_decode, br"\x")
+        self.assertRaises(ValueError, codecs.escape_decode, br"[\x]")
+        self.assertEqual(codecs.escape_decode(br"[\x]\x", "ignore"), (b"[]", 6))
+        self.assertEqual(codecs.escape_decode(br"[\x]\x", "replace"), (b"[?]?", 6))
+        self.assertRaises(ValueError, codecs.escape_decode, br"\x0")
+        self.assertRaises(ValueError, codecs.escape_decode, br"[\x0]")
+        self.assertEqual(codecs.escape_decode(br"[\x0]\x0", "ignore"), (b"[]", 8))
+        self.assertEqual(codecs.escape_decode(br"[\x0]\x0", "replace"), (b"[?]?", 8))
+
 class RecodingTest(unittest.TestCase):
     def test_recoding(self):
         f = io.BytesIO()
index e19c06948da5ee00a83db6b09209a736a8548439..4dd981b277bff0fee7bcfbd0ecba8eb50abf11af 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ What's New in Python 3.2.4
 Core and Builtins
 -----------------
 
+- Issue #16975: Fix error handling bug in the escape-decode bytes decoder.
+
 - Issue #14850: Now a charmap decoder treats U+FFFE as "undefined mapping"
   in any mapping, not only in a string.
 
index ef3a5a12a2361e241b3efc1d7601eb7d1d7d6ae9..c0f5aff7dc23e60df298fece49c617715aa2f63b 100644 (file)
@@ -484,6 +484,10 @@ PyObject *PyBytes_DecodeEscape(const char *s,
                              errors);
                 goto failed;
             }
+            /* skip \x */
+            if (s < end && Py_ISXDIGIT(s[0]))
+                s++; /* and a hexdigit */
+            break;
         default:
             *p++ = '\\';
             s--;