Skip to content

Commit 01b3a08

Browse files
Issue #16975: Fix error handling bug in the escape-decode decoder.
1 parent 1c60c7a commit 01b3a08

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

Lib/test/test_codecs.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,50 @@ class EscapeDecodeTest(unittest.TestCase):
730730
def test_empty(self):
731731
self.assertEqual(codecs.escape_decode(""), ("", 0))
732732

733+
def test_raw(self):
734+
for b in ''.join(map(chr, range(256))):
735+
if b != '\\':
736+
self.assertEqual(codecs.escape_decode(b + '0'),
737+
(b + '0', 2))
738+
739+
def test_escape(self):
740+
self.assertEqual(codecs.escape_decode(b"[\\\n]"), (b"[]", 4))
741+
self.assertEqual(codecs.escape_decode(br'[\"]'), (b'["]', 4))
742+
self.assertEqual(codecs.escape_decode(br"[\']"), (b"[']", 4))
743+
self.assertEqual(codecs.escape_decode(br"[\\]"), (br"[\]", 4))
744+
self.assertEqual(codecs.escape_decode(br"[\a]"), (b"[\x07]", 4))
745+
self.assertEqual(codecs.escape_decode(br"[\b]"), (b"[\x08]", 4))
746+
self.assertEqual(codecs.escape_decode(br"[\t]"), (b"[\x09]", 4))
747+
self.assertEqual(codecs.escape_decode(br"[\n]"), (b"[\x0a]", 4))
748+
self.assertEqual(codecs.escape_decode(br"[\v]"), (b"[\x0b]", 4))
749+
self.assertEqual(codecs.escape_decode(br"[\f]"), (b"[\x0c]", 4))
750+
self.assertEqual(codecs.escape_decode(br"[\r]"), (b"[\x0d]", 4))
751+
self.assertEqual(codecs.escape_decode(br"[\7]"), (b"[\x07]", 4))
752+
self.assertEqual(codecs.escape_decode(br"[\8]"), (br"[\8]", 4))
753+
self.assertEqual(codecs.escape_decode(br"[\78]"), (b"[\x078]", 5))
754+
self.assertEqual(codecs.escape_decode(br"[\41]"), (b"[!]", 5))
755+
self.assertEqual(codecs.escape_decode(br"[\418]"), (b"[!8]", 6))
756+
self.assertEqual(codecs.escape_decode(br"[\101]"), (b"[A]", 6))
757+
self.assertEqual(codecs.escape_decode(br"[\1010]"), (b"[A0]", 7))
758+
self.assertEqual(codecs.escape_decode(br"[\501]"), (b"[A]", 6))
759+
self.assertEqual(codecs.escape_decode(br"[\x41]"), (b"[A]", 6))
760+
self.assertEqual(codecs.escape_decode(br"[\X41]"), (br"[\X41]", 6))
761+
self.assertEqual(codecs.escape_decode(br"[\x410]"), (b"[A0]", 7))
762+
for b in ''.join(map(chr, range(256))):
763+
if b not in '\n"\'\\abtnvfr01234567x':
764+
self.assertEqual(codecs.escape_decode('\\' + b),
765+
('\\' + b, 2))
766+
767+
def test_errors(self):
768+
self.assertRaises(ValueError, codecs.escape_decode, br"\x")
769+
self.assertRaises(ValueError, codecs.escape_decode, br"[\x]")
770+
self.assertEqual(codecs.escape_decode(br"[\x]\x", "ignore"), (b"[]", 6))
771+
self.assertEqual(codecs.escape_decode(br"[\x]\x", "replace"), (b"[?]?", 6))
772+
self.assertRaises(ValueError, codecs.escape_decode, br"\x0")
773+
self.assertRaises(ValueError, codecs.escape_decode, br"[\x0]")
774+
self.assertEqual(codecs.escape_decode(br"[\x0]\x0", "ignore"), (b"[]", 8))
775+
self.assertEqual(codecs.escape_decode(br"[\x0]\x0", "replace"), (b"[?]?", 8))
776+
733777
class RecodingTest(unittest.TestCase):
734778
def test_recoding(self):
735779
f = StringIO.StringIO()

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ What's New in Python 2.7.4
99
Core and Builtins
1010
-----------------
1111

12+
- Issue #16975: Fix error handling bug in the escape-decode decoder.
13+
1214
- Issue #14850: Now a charmap decoder treats U+FFFE as "undefined mapping"
1315
in any mapping, not only in a Unicode string.
1416

Objects/stringobject.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,10 @@ PyObject *PyString_DecodeEscape(const char *s,
726726
errors);
727727
goto failed;
728728
}
729+
/* skip \x */
730+
if (s < end && isxdigit(Py_CHARMASK(s[0])))
731+
s++; /* and a hexdigit */
732+
break;
729733
#ifndef Py_USING_UNICODE
730734
case 'u':
731735
case 'U':

0 commit comments

Comments
 (0)