@@ -3191,7 +3191,7 @@ static int
31913191batch_list_exact (PickleState * state , PicklerObject * self , PyObject * obj )
31923192{
31933193 PyObject * item = NULL ;
3194- Py_ssize_t this_batch , total ;
3194+ Py_ssize_t this_batch , total , list_size ;
31953195
31963196 const char append_op = APPEND ;
31973197 const char appends_op = APPENDS ;
@@ -3200,14 +3200,18 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj)
32003200 assert (obj != NULL );
32013201 assert (self -> proto > 0 );
32023202 assert (PyList_CheckExact (obj ));
3203- assert (PyList_GET_SIZE (obj ));
3203+
3204+ list_size = PyList_GET_SIZE (obj );
32043205
32053206 /* Write in batches of BATCHSIZE. */
32063207 total = 0 ;
32073208 do {
3208- if (PyList_GET_SIZE (obj ) - total == 1 ) {
3209- item = PyList_GET_ITEM (obj , total );
3210- Py_INCREF (item );
3209+ if (list_size - total == 1 ) {
3210+ item = PyList_GetItemRef (obj , total );
3211+ if (item == NULL ) {
3212+ _PyErr_FormatNote ("when serializing %T item %zd" , obj , total );
3213+ return -1 ;
3214+ }
32113215 int err = save (state , self , item , 0 );
32123216 Py_DECREF (item );
32133217 if (err < 0 ) {
@@ -3222,8 +3226,11 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj)
32223226 if (_Pickler_Write (self , & mark_op , 1 ) < 0 )
32233227 return -1 ;
32243228 while (total < PyList_GET_SIZE (obj )) {
3225- item = PyList_GET_ITEM (obj , total );
3226- Py_INCREF (item );
3229+ item = PyList_GetItemRef (obj , total );
3230+ if (item == NULL ) {
3231+ _PyErr_FormatNote ("when serializing %T item %zd" , obj , total );
3232+ return -1 ;
3233+ }
32273234 int err = save (state , self , item , 0 );
32283235 Py_DECREF (item );
32293236 if (err < 0 ) {
@@ -3236,8 +3243,14 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj)
32363243 }
32373244 if (_Pickler_Write (self , & appends_op , 1 ) < 0 )
32383245 return -1 ;
3246+ if (PyList_GET_SIZE (obj ) != list_size ) {
3247+ PyErr_Format (
3248+ PyExc_RuntimeError ,
3249+ "list changed size during iteration" );
3250+ return -1 ;
3251+ }
32393252
3240- } while (total < PyList_GET_SIZE ( obj ) );
3253+ } while (total < list_size );
32413254
32423255 return 0 ;
32433256}
0 commit comments