@@ -3179,7 +3179,7 @@ static int
31793179batch_list_exact (PickleState * state , PicklerObject * self , PyObject * obj )
31803180{
31813181 PyObject * item = NULL ;
3182- Py_ssize_t this_batch , total ;
3182+ Py_ssize_t this_batch , total , list_size ;
31833183
31843184 const char append_op = APPEND ;
31853185 const char appends_op = APPENDS ;
@@ -3188,14 +3188,18 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj)
31883188 assert (obj != NULL );
31893189 assert (self -> proto > 0 );
31903190 assert (PyList_CheckExact (obj ));
3191- assert (PyList_GET_SIZE (obj ));
3191+
3192+ list_size = PyList_GET_SIZE (obj );
31923193
31933194 /* Write in batches of BATCHSIZE. */
31943195 total = 0 ;
31953196 do {
3196- if (PyList_GET_SIZE (obj ) - total == 1 ) {
3197- item = PyList_GET_ITEM (obj , total );
3198- Py_INCREF (item );
3197+ if (list_size - total == 1 ) {
3198+ item = PyList_GetItemRef (obj , total );
3199+ if (item == NULL ) {
3200+ _PyErr_FormatNote ("when serializing %T item %zd" , obj , total );
3201+ return -1 ;
3202+ }
31993203 int err = save (state , self , item , 0 );
32003204 Py_DECREF (item );
32013205 if (err < 0 ) {
@@ -3210,8 +3214,11 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj)
32103214 if (_Pickler_Write (self , & mark_op , 1 ) < 0 )
32113215 return -1 ;
32123216 while (total < PyList_GET_SIZE (obj )) {
3213- item = PyList_GET_ITEM (obj , total );
3214- Py_INCREF (item );
3217+ item = PyList_GetItemRef (obj , total );
3218+ if (item == NULL ) {
3219+ _PyErr_FormatNote ("when serializing %T item %zd" , obj , total );
3220+ return -1 ;
3221+ }
32153222 int err = save (state , self , item , 0 );
32163223 Py_DECREF (item );
32173224 if (err < 0 ) {
@@ -3224,8 +3231,14 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj)
32243231 }
32253232 if (_Pickler_Write (self , & appends_op , 1 ) < 0 )
32263233 return -1 ;
3234+ if (PyList_GET_SIZE (obj ) != list_size ) {
3235+ PyErr_Format (
3236+ PyExc_RuntimeError ,
3237+ "list changed size during iteration" );
3238+ return -1 ;
3239+ }
32273240
3228- } while (total < PyList_GET_SIZE ( obj ) );
3241+ } while (total < list_size );
32293242
32303243 return 0 ;
32313244}
0 commit comments