From c559135c931789ebc752ae68814858c398cb798b Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 12 Jan 2026 20:23:05 +0200 Subject: [PATCH] gh-143196: Fix crash in non-standard use of internal JSON encoder object (GH-143618) 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 | 31 +++++++++++++++++++ ...-01-09-17-50-26.gh-issue-143196.WxKxzU.rst | 3 ++ Modules/_json.c | 1 + 3 files changed, 35 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 682014cfd5b3..4c0aa5f993b3 100644 --- a/Lib/test/test_json/test_speedups.py +++ b/Lib/test/test_json/test_speedups.py @@ -80,3 +80,34 @@ class TestEncode(CTest): 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) + expected = ( + '[\n' + '\t"spam", \n' + '\t{\n' + '\t\t"ham": "eggs"\n' + '\t}\n' + ']') + self.assertEqual(enc(['spam', {'ham': 'eggs'}], 0)[0], expected) + self.assertEqual(enc(['spam', {'ham': 'eggs'}], -3)[0], expected) + expected2 = ( + '[\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], expected2) + 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 000000000000..9143cf2aeccc --- /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 78a85496575a..c7e62c4fe55c 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1460,6 +1460,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); -- 2.47.3