From 7a066ad02038583b227c0293b8049ad6be87d5fe Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 12 Jan 2026 19:50:40 +0100 Subject: [PATCH] [3.14] gh-143196: Fix crash in non-standard use of internal JSON encoder object (GH-143618) (GH-143748) 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. (cherry picked from commit c559135c931789ebc752ae68814858c398cb798b) Co-authored-by: Serhiy Storchaka --- 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 682014cfd5b..4c0aa5f993b 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 00000000000..9143cf2aecc --- /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 b3959cfe4a1..39ec9a969cf 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1383,6 +1383,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);