gh-92930: _pickle.c: Acquire strong references before calling save() … · python/cpython@54fe3d5

GitHub

@@ -3006,7 +3006,10 @@ batch_list_exact(PicklerObject *self, PyObject *obj)

3006300630073007if (PyList_GET_SIZE(obj) ==1) {

30083008item=PyList_GET_ITEM(obj, 0);

3009-if (save(self, item, 0) <0)

3009+Py_INCREF(item);

3010+interr=save(self, item, 0);

3011+Py_DECREF(item);

3012+if (err<0)

30103013return-1;

30113014if (_Pickler_Write(self, &append_op, 1) <0)

30123015return-1;

@@ -3021,7 +3024,10 @@ batch_list_exact(PicklerObject *self, PyObject *obj)

30213024return-1;

30223025while (total<PyList_GET_SIZE(obj)) {

30233026item=PyList_GET_ITEM(obj, total);

3024-if (save(self, item, 0) <0)

3027+Py_INCREF(item);

3028+interr=save(self, item, 0);

3029+Py_DECREF(item);

3030+if (err<0)

30253031return-1;

30263032total++;

30273033if (++this_batch==BATCHSIZE)

@@ -3259,10 +3265,16 @@ batch_dict_exact(PicklerObject *self, PyObject *obj)

32593265/* Special-case len(d) == 1 to save space. */

32603266if (dict_size==1) {

32613267PyDict_Next(obj, &ppos, &key, &value);

3262-if (save(self, key, 0) <0)

3263-return-1;

3264-if (save(self, value, 0) <0)

3265-return-1;

3268+Py_INCREF(key);

3269+Py_INCREF(value);

3270+if (save(self, key, 0) <0) {

3271+ goto error;

3272+ }

3273+if (save(self, value, 0) <0) {

3274+ goto error;

3275+ }

3276+Py_CLEAR(key);

3277+Py_CLEAR(value);

32663278if (_Pickler_Write(self, &setitem_op, 1) <0)

32673279return-1;

32683280return0;

@@ -3274,10 +3286,16 @@ batch_dict_exact(PicklerObject *self, PyObject *obj)

32743286if (_Pickler_Write(self, &mark_op, 1) <0)

32753287return-1;

32763288while (PyDict_Next(obj, &ppos, &key, &value)) {

3277-if (save(self, key, 0) <0)

3278-return-1;

3279-if (save(self, value, 0) <0)

3280-return-1;

3289+Py_INCREF(key);

3290+Py_INCREF(value);

3291+if (save(self, key, 0) <0) {

3292+ goto error;

3293+ }

3294+if (save(self, value, 0) <0) {

3295+ goto error;

3296+ }

3297+Py_CLEAR(key);

3298+Py_CLEAR(value);

32813299if (++i==BATCHSIZE)

32823300break;

32833301 }

@@ -3292,6 +3310,10 @@ batch_dict_exact(PicklerObject *self, PyObject *obj)

3292331032933311 } while (i==BATCHSIZE);

32943312return0;

3313+error:

3314+Py_XDECREF(key);

3315+Py_XDECREF(value);

3316+return-1;

32953317}

3296331832973319staticint

@@ -3409,7 +3431,10 @@ save_set(PicklerObject *self, PyObject *obj)

34093431if (_Pickler_Write(self, &mark_op, 1) <0)

34103432return-1;

34113433while (_PySet_NextEntry(obj, &ppos, &item, &hash)) {

3412-if (save(self, item, 0) <0)

3434+Py_INCREF(item);

3435+interr=save(self, item, 0);

3436+Py_CLEAR(item);

3437+if (err<0)

34133438return-1;

34143439if (++i==BATCHSIZE)

34153440break;