]> granicus.if.org Git - python/commitdiff
Issue #12983: Bytes literals with invalid \x escape now raise a SyntaxError
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 10 Feb 2013 15:36:00 +0000 (17:36 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 10 Feb 2013 15:36:00 +0000 (17:36 +0200)
and a full traceback including line number.

Lib/test/test_strlit.py
Misc/NEWS
Objects/bytesobject.c
Python/ast.c

index 6bdc6e4e8a244a8143b64901f590b732108e1092..a4ae19803c9dbf5e690dcaa466c282dcf4dc283b 100644 (file)
@@ -50,6 +50,10 @@ f = '\u1881'
 assert ord(f) == 0x1881
 g = r'\u1881'
 assert list(map(ord, g)) == [92, 117, 49, 56, 56, 49]
+h = '\U0001d120'
+assert ord(h) == 0x1d120
+i = r'\U0001d120'
+assert list(map(ord, i)) == [92, 85, 48, 48, 48, 49, 100, 49, 50, 48]
 """
 
 
@@ -82,6 +86,24 @@ class TestLiterals(unittest.TestCase):
         self.assertEqual(eval(""" '\x81' """), chr(0x81))
         self.assertEqual(eval(r""" '\u1881' """), chr(0x1881))
         self.assertEqual(eval(""" '\u1881' """), chr(0x1881))
+        self.assertEqual(eval(r""" '\U0001d120' """), chr(0x1d120))
+        self.assertEqual(eval(""" '\U0001d120' """), chr(0x1d120))
+
+    def test_eval_str_incomplete(self):
+        self.assertRaises(SyntaxError, eval, r""" '\x' """)
+        self.assertRaises(SyntaxError, eval, r""" '\x0' """)
+        self.assertRaises(SyntaxError, eval, r""" '\u' """)
+        self.assertRaises(SyntaxError, eval, r""" '\u0' """)
+        self.assertRaises(SyntaxError, eval, r""" '\u00' """)
+        self.assertRaises(SyntaxError, eval, r""" '\u000' """)
+        self.assertRaises(SyntaxError, eval, r""" '\U' """)
+        self.assertRaises(SyntaxError, eval, r""" '\U0' """)
+        self.assertRaises(SyntaxError, eval, r""" '\U00' """)
+        self.assertRaises(SyntaxError, eval, r""" '\U000' """)
+        self.assertRaises(SyntaxError, eval, r""" '\U0000' """)
+        self.assertRaises(SyntaxError, eval, r""" '\U00000' """)
+        self.assertRaises(SyntaxError, eval, r""" '\U000000' """)
+        self.assertRaises(SyntaxError, eval, r""" '\U0000000' """)
 
     def test_eval_str_raw(self):
         self.assertEqual(eval(""" r'x' """), 'x')
@@ -91,6 +113,8 @@ class TestLiterals(unittest.TestCase):
         self.assertEqual(eval(""" r'\x81' """), chr(0x81))
         self.assertEqual(eval(r""" r'\u1881' """), '\\' + 'u1881')
         self.assertEqual(eval(""" r'\u1881' """), chr(0x1881))
+        self.assertEqual(eval(r""" r'\U0001d120' """), '\\' + 'U0001d120')
+        self.assertEqual(eval(""" r'\U0001d120' """), chr(0x1d120))
 
     def test_eval_bytes_normal(self):
         self.assertEqual(eval(""" b'x' """), b'x')
@@ -100,6 +124,12 @@ class TestLiterals(unittest.TestCase):
         self.assertRaises(SyntaxError, eval, """ b'\x81' """)
         self.assertEqual(eval(r""" b'\u1881' """), b'\\' + b'u1881')
         self.assertRaises(SyntaxError, eval, """ b'\u1881' """)
+        self.assertEqual(eval(r""" b'\U0001d120' """), b'\\' + b'U0001d120')
+        self.assertRaises(SyntaxError, eval, """ b'\U0001d120' """)
+
+    def test_eval_bytes_incomplete(self):
+        self.assertRaises(SyntaxError, eval, r""" b'\x' """)
+        self.assertRaises(SyntaxError, eval, r""" b'\x0' """)
 
     def test_eval_bytes_raw(self):
         self.assertEqual(eval(""" br'x' """), b'x')
@@ -109,6 +139,12 @@ class TestLiterals(unittest.TestCase):
         self.assertRaises(SyntaxError, eval, """ br'\x81' """)
         self.assertEqual(eval(r""" br'\u1881' """), b"\\" + b"u1881")
         self.assertRaises(SyntaxError, eval, """ br'\u1881' """)
+        self.assertEqual(eval(r""" br'\U0001d120' """), b"\\" + b"U0001d120")
+        self.assertRaises(SyntaxError, eval, """ br'\U0001d120' """)
+        self.assertRaises(SyntaxError, eval, """ rb'' """)
+        self.assertRaises(SyntaxError, eval, """ bb'' """)
+        self.assertRaises(SyntaxError, eval, """ rr'' """)
+        self.assertRaises(SyntaxError, eval, """ brr'' """)
 
     def check_encoding(self, encoding, extra=""):
         modname = "xx_" + encoding.replace("-", "_")
index c4793c70d0f132497f82da7b550b9d236262c47c..6ce6f4788fa63663ce45ee8b3326d3be6e416624 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.2.4
 Core and Builtins
 -----------------
 
+- Issue #12983: Bytes literals with invalid \x escape now raise a SyntaxError
+  and a full traceback including line number.
+
 - Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.)
   in the interpreter.
 
index b60a8b06c336cbe6d87ef8bd506976ba012e52c9..cb5679bc38b6fa47fe3051657d3477bcbaf12cf2 100644 (file)
@@ -469,8 +469,9 @@ PyObject *PyBytes_DecodeEscape(const char *s,
                 break;
             }
             if (!errors || strcmp(errors, "strict") == 0) {
-                PyErr_SetString(PyExc_ValueError,
-                                "invalid \\x escape");
+                PyErr_Format(PyExc_ValueError,
+                             "invalid \\x escape at position %d",
+                              s - 2 - (end - len));
                 goto failed;
             }
             if (strcmp(errors, "replace") == 0) {
index e395c5aa788e2697137afb1c16cbe5b9976ae0e2..edcd18b9b8ffd7219f5bc4d21ce6d951e28ad9c8 100644 (file)
@@ -1368,20 +1368,24 @@ ast_for_atom(struct compiling *c, const node *n)
     case STRING: {
         PyObject *str = parsestrplus(c, n, &bytesmode);
         if (!str) {
-            if (PyErr_ExceptionMatches(PyExc_UnicodeError)) {
+            const char *errtype = NULL;
+            if (PyErr_ExceptionMatches(PyExc_UnicodeError))
+                errtype = "unicode error";
+            else if (PyErr_ExceptionMatches(PyExc_ValueError))
+                errtype = "value error";
+            if (errtype) {
+                char buf[128];
                 PyObject *type, *value, *tback, *errstr;
                 PyErr_Fetch(&type, &value, &tback);
                 errstr = PyObject_Str(value);
                 if (errstr) {
-                    char *s = "";
-                    char buf[128];
-                    s = _PyUnicode_AsString(errstr);
-                    PyOS_snprintf(buf, sizeof(buf), "(unicode error) %s", s);
-                    ast_error(n, buf);
+                    char *s = _PyUnicode_AsString(errstr);
+                    PyOS_snprintf(buf, sizeof(buf), "(%s) %s", errtype, s);
                     Py_DECREF(errstr);
                 } else {
-                    ast_error(n, "(unicode error) unknown error");
+                    PyOS_snprintf(buf, sizeof(buf), "(%s) unknown error", errtype);
                 }
+                ast_error(n, buf);
                 Py_DECREF(type);
                 Py_DECREF(value);
                 Py_XDECREF(tback);