From 7fa02310089c59399042cc5654e6196393171057 Mon Sep 17 00:00:00 2001 From: Aivars Kalvans Date: Mon, 9 Nov 2026 11:24:37 +0200 Subject: [PATCH] json: use a single dict probe for circular-reference markers --- Modules/_json.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Modules/_json.c b/Modules/_json.c index 3a724a3e72b185..1a7e90e9f529c8 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1808,17 +1808,18 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, } if (s->markers != Py_None) { - int has_key; ident = PyLong_FromVoidPtr(dct); if (ident == NULL) goto bail; - has_key = PyDict_Contains(s->markers, ident); - if (has_key) { - if (has_key != -1) - PyErr_SetString(PyExc_ValueError, "Circular reference detected"); + PyObject *existing = NULL; + int res = PyDict_SetDefaultRef(s->markers, ident, dct, &existing); + if (res < 0) { goto bail; } - if (PyDict_SetItem(s->markers, ident, dct)) { + Py_DECREF(existing); + if (res > 0) { + /* The key was already present: circular reference. */ + PyErr_SetString(PyExc_ValueError, "Circular reference detected"); goto bail; } } @@ -1928,17 +1929,18 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer, } if (s->markers != Py_None) { - int has_key; ident = PyLong_FromVoidPtr(seq); if (ident == NULL) goto bail; - has_key = PyDict_Contains(s->markers, ident); - if (has_key) { - if (has_key != -1) - PyErr_SetString(PyExc_ValueError, "Circular reference detected"); + PyObject *existing = NULL; + int res = PyDict_SetDefaultRef(s->markers, ident, seq, &existing); + if (res < 0) { goto bail; } - if (PyDict_SetItem(s->markers, ident, seq)) { + Py_DECREF(existing); + if (res > 0) { + /* The key was already present: circular reference. */ + PyErr_SetString(PyExc_ValueError, "Circular reference detected"); goto bail; } }