@@ -1733,15 +1733,14 @@ _encoder_iterate_mapping_lock_held(PyEncoderObject *s, PyUnicodeWriter *writer,
17331733 PyObject * key , * value ;
17341734 for (Py_ssize_t i = 0 ; i < PyList_GET_SIZE (items ); i ++ ) {
17351735 PyObject * item = PyList_GET_ITEM (items , i );
1736- #ifdef Py_GIL_DISABLED
1737- // gh-119438: in the free-threading build the critical section on items can get suspended
1736+
1737+ // GH-142831: The item must be strong-referenced to avoid UAF
1738+ // if the user code modifies the list during iteration.
17381739 Py_INCREF (item );
1739- #endif
1740+
17401741 if (!PyTuple_Check (item ) || PyTuple_GET_SIZE (item ) != 2 ) {
17411742 PyErr_SetString (PyExc_ValueError , "items must return 2-tuples" );
1742- #ifdef Py_GIL_DISABLED
17431743 Py_DECREF (item );
1744- #endif
17451744 return -1 ;
17461745 }
17471746
@@ -1750,14 +1749,10 @@ _encoder_iterate_mapping_lock_held(PyEncoderObject *s, PyUnicodeWriter *writer,
17501749 if (encoder_encode_key_value (s , writer , first , dct , key , value ,
17511750 indent_level , indent_cache ,
17521751 separator ) < 0 ) {
1753- #ifdef Py_GIL_DISABLED
17541752 Py_DECREF (item );
1755- #endif
17561753 return -1 ;
17571754 }
1758- #ifdef Py_GIL_DISABLED
17591755 Py_DECREF (item );
1760- #endif
17611756 }
17621757
17631758 return 0 ;
@@ -1772,24 +1767,20 @@ _encoder_iterate_dict_lock_held(PyEncoderObject *s, PyUnicodeWriter *writer,
17721767 PyObject * key , * value ;
17731768 Py_ssize_t pos = 0 ;
17741769 while (PyDict_Next (dct , & pos , & key , & value )) {
1775- #ifdef Py_GIL_DISABLED
1776- // gh-119438: in the free-threading build the critical section on dct can get suspended
1770+ // GH-142831: The key and value must be strong-referenced to avoid UAF
1771+ // if the user code modifies the dict during iteration.
17771772 Py_INCREF (key );
17781773 Py_INCREF (value );
1779- #endif
1774+
17801775 if (encoder_encode_key_value (s , writer , first , dct , key , value ,
17811776 indent_level , indent_cache ,
17821777 separator ) < 0 ) {
1783- #ifdef Py_GIL_DISABLED
17841778 Py_DECREF (key );
17851779 Py_DECREF (value );
1786- #endif
17871780 return -1 ;
17881781 }
1789- #ifdef Py_GIL_DISABLED
17901782 Py_DECREF (key );
17911783 Py_DECREF (value );
1792- #endif
17931784 }
17941785 return 0 ;
17951786}
@@ -1893,28 +1884,23 @@ _encoder_iterate_fast_seq_lock_held(PyEncoderObject *s, PyUnicodeWriter *writer,
18931884{
18941885 for (Py_ssize_t i = 0 ; i < PySequence_Fast_GET_SIZE (s_fast ); i ++ ) {
18951886 PyObject * obj = PySequence_Fast_GET_ITEM (s_fast , i );
1896- #ifdef Py_GIL_DISABLED
1897- // gh-119438: in the free-threading build the critical section on s_fast can get suspended
1887+
1888+ // GH-142831: The object must be strong-referenced to avoid UAF
1889+ // if the user code modifies the sequence during iteration.
18981890 Py_INCREF (obj );
1899- #endif
1891+
19001892 if (i ) {
19011893 if (PyUnicodeWriter_WriteStr (writer , separator ) < 0 ) {
1902- #ifdef Py_GIL_DISABLED
19031894 Py_DECREF (obj );
1904- #endif
19051895 return -1 ;
19061896 }
19071897 }
19081898 if (encoder_listencode_obj (s , writer , obj , indent_level , indent_cache )) {
19091899 _PyErr_FormatNote ("when serializing %T item %zd" , seq , i );
1910- #ifdef Py_GIL_DISABLED
19111900 Py_DECREF (obj );
1912- #endif
19131901 return -1 ;
19141902 }
1915- #ifdef Py_GIL_DISABLED
19161903 Py_DECREF (obj );
1917- #endif
19181904 }
19191905 return 0 ;
19201906}
0 commit comments