From 919295b3884d471249e13278420c7d21b54f2917 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Jan 2026 17:50:38 +0200 Subject: [PATCH 1/2] gh-143196: Fix crash in non-standard use of internal JSON encoder object The internal encoder object returned by undocumented function json.encoder.c_make_encoder() (aka _json.make_encoder()) crashed when it was called with non-zero second argument. --- Lib/test/test_json/test_speedups.py | 35 +++++++++++++++++++ ...-01-09-17-50-26.gh-issue-143196.WxKxzU.rst | 3 ++ Modules/_json.c | 1 + 3 files changed, 39 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst diff --git a/Lib/test/test_json/test_speedups.py b/Lib/test/test_json/test_speedups.py index 682014cfd5b344..4eeb7b002b4415 100644 --- a/Lib/test/test_json/test_speedups.py +++ b/Lib/test/test_json/test_speedups.py @@ -80,3 +80,38 @@ def test(name): def test_unsortable_keys(self): with self.assertRaises(TypeError): self.json.encoder.JSONEncoder(sort_keys=True).encode({'a': 1, 1: 'a'}) + + def test_current_indent_level(self): + enc = self.json.encoder.c_make_encoder( + markers=None, + default=str, + encoder=self.json.encoder.c_encode_basestring, + indent='\t', + key_separator=': ', + item_separator=', ', + sort_keys=False, + skipkeys=False, + allow_nan=False) + self.assertEqual(enc(['spam', {'ham': 'eggs'}], 0)[0], + '[\n' + '\t"spam", \n' + '\t{\n' + '\t\t"ham": "eggs"\n' + '\t}\n' + ']') + self.assertEqual(enc(['spam', {'ham': 'eggs'}], 3)[0], + '[\n' + '\t\t\t\t"spam", \n' + '\t\t\t\t{\n' + '\t\t\t\t\t"ham": "eggs"\n' + '\t\t\t\t}\n' + '\t\t\t]') + self.assertEqual(enc(['spam', {'ham': 'eggs'}], -3)[0], + '[\n' + '\t"spam", \n' + '\t{\n' + '\t\t"ham": "eggs"\n' + '\t}\n' + ']') + self.assertRaises(TypeError, enc, ['spam', {'ham': 'eggs'}], 3.0) + self.assertRaises(TypeError, enc, ['spam', {'ham': 'eggs'}]) diff --git a/Misc/NEWS.d/next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst b/Misc/NEWS.d/next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst new file mode 100644 index 00000000000000..a9e5997ffaf4ab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst @@ -0,0 +1,3 @@ +Fix crash when the internal encoder object returned by undocumented function +:func:`json.encoder.c_make_encoder` was called with non-zero second +(*_current_indent_level*) argument. diff --git a/Modules/_json.c b/Modules/_json.c index 14714d4b346546..e2ee96ba39fe03 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1459,6 +1459,7 @@ encoder_call(PyObject *op, PyObject *args, PyObject *kwds) return NULL; } } + indent_level = 0; if (encoder_listencode_obj(self, writer, obj, indent_level, indent_cache)) { PyUnicodeWriter_Discard(writer); Py_XDECREF(indent_cache); From 4d0d3bb6a084b8487528433183aa57a4393c1d1b Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Jan 2026 18:47:12 +0200 Subject: [PATCH 2/2] Fix documentation for json.encoder.c_make_encoder --- .../next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst b/Misc/NEWS.d/next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst index a9e5997ffaf4ab..9143cf2aeccc9e 100644 --- a/Misc/NEWS.d/next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst +++ b/Misc/NEWS.d/next/Library/2026-01-09-17-50-26.gh-issue-143196.WxKxzU.rst @@ -1,3 +1,3 @@ Fix crash when the internal encoder object returned by undocumented function -:func:`json.encoder.c_make_encoder` was called with non-zero second +:func:`!json.encoder.c_make_encoder` was called with non-zero second (*_current_indent_level*) argument.