Commit 01b3a08f authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #16975: Fix error handling bug in the escape-decode decoder.

parent 1c60c7ac
...@@ -730,6 +730,50 @@ class EscapeDecodeTest(unittest.TestCase): ...@@ -730,6 +730,50 @@ class EscapeDecodeTest(unittest.TestCase):
def test_empty(self): def test_empty(self):
self.assertEqual(codecs.escape_decode(""), ("", 0)) self.assertEqual(codecs.escape_decode(""), ("", 0))
def test_raw(self):
for b in ''.join(map(chr, range(256))):
if b != '\\':
self.assertEqual(codecs.escape_decode(b + '0'),
(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 ''.join(map(chr, range(256))):
if b not in '\n"\'\\abtnvfr01234567x':
self.assertEqual(codecs.escape_decode('\\' + b),
('\\' + 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): class RecodingTest(unittest.TestCase):
def test_recoding(self): def test_recoding(self):
f = StringIO.StringIO() f = StringIO.StringIO()
......
...@@ -9,6 +9,8 @@ What's New in Python 2.7.4 ...@@ -9,6 +9,8 @@ What's New in Python 2.7.4
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #16975: Fix error handling bug in the escape-decode decoder.
- Issue #14850: Now a charmap decoder treats U+FFFE as "undefined mapping" - Issue #14850: Now a charmap decoder treats U+FFFE as "undefined mapping"
in any mapping, not only in a Unicode string. in any mapping, not only in a Unicode string.
......
...@@ -726,6 +726,10 @@ PyObject *PyString_DecodeEscape(const char *s, ...@@ -726,6 +726,10 @@ PyObject *PyString_DecodeEscape(const char *s,
errors); errors);
goto failed; goto failed;
} }
/* skip \x */
if (s < end && isxdigit(Py_CHARMASK(s[0])))
s++; /* and a hexdigit */
break;
#ifndef Py_USING_UNICODE #ifndef Py_USING_UNICODE
case 'u': case 'u':
case 'U': case 'U':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment