From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:15:21 +0000 (+0200) Subject: [3.15] gh-152052: Fix misleading `json` error for `\uXXXX` escape at the end of input... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3e6bdafd2804c1bf7d4cb31fed3f983fd5936ba;p=thirdparty%2FPython%2Fcpython.git [3.15] gh-152052: Fix misleading `json` error for `\uXXXX` escape at the end of input (GH-152053) (#152283) (cherry picked from commit 588be7af08c04d63c1a920539c64885fbc4c6d38) Co-authored-by: tonghuaroot (童话) Co-authored-by: Stan Ulbrych --- diff --git a/Lib/test/test_json/test_fail.py b/Lib/test/test_json/test_fail.py index 79c44af2fbf0..7f99a6331d36 100644 --- a/Lib/test/test_json/test_fail.py +++ b/Lib/test/test_json/test_fail.py @@ -144,6 +144,13 @@ class TestFail: ('"', 'Unterminated string starting at', 0), ('"spam', 'Unterminated string starting at', 0), ] + # A complete \uXXXX escape at end of input leaves it unterminated. + test_cases += [ + (r'"\u0041', 'Unterminated string starting at', 0), + (r'"\ud834', 'Unterminated string starting at', 0), + (r'"\ud834\udd1e', 'Unterminated string starting at', 0), + (r'{"a": "\u0041', 'Unterminated string starting at', 6), + ] for data, msg, idx in test_cases: with self.assertRaises(self.JSONDecodeError) as cm: self.loads(data) diff --git a/Lib/test/test_json/test_scanstring.py b/Lib/test/test_json/test_scanstring.py index 9a6cdfe12d26..a52b01c71130 100644 --- a/Lib/test/test_json/test_scanstring.py +++ b/Lib/test/test_json/test_scanstring.py @@ -137,6 +137,9 @@ class TestScanstring: '"\\ud834\\u-123"', '"\\ud834\\u+123"', '"\\ud834\\u1_23"', + # Truncated or non-hex \uXXXX escape at end of input. + '"\\u004', + '"\\uXYZW', ] for s in bad_escapes: with self.assertRaises(self.JSONDecodeError, msg=s): diff --git a/Misc/NEWS.d/next/Library/2026-06-24-12-00-00.gh-issue-152052.yBssDE.rst b/Misc/NEWS.d/next/Library/2026-06-24-12-00-00.gh-issue-152052.yBssDE.rst new file mode 100644 index 000000000000..f9ffbbd342fc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-24-12-00-00.gh-issue-152052.yBssDE.rst @@ -0,0 +1,2 @@ +The :mod:`json` C accelerator now correctly reports an unterminated string for a +``\uXXXX`` escape at the end of the input. diff --git a/Modules/_json.c b/Modules/_json.c index 6c4f38834631..858702e6f450 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -574,7 +574,7 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next c = 0; next++; end = next + 4; - if (end >= len) { + if (end > len) { raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1); goto bail; }