@@ -11,12 +11,14 @@ annotated by François Pinard, and converted to C by Raymond Hettinger.
1111static int
1212_siftdown (PyListObject * heap , Py_ssize_t startpos , Py_ssize_t pos )
1313{
14- PyObject * newitem , * parent ;
14+ PyObject * newitem , * parent , * olditem ;
1515 int cmp ;
1616 Py_ssize_t parentpos ;
17+ Py_ssize_t size ;
1718
1819 assert (PyList_Check (heap ));
19- if (pos >= PyList_GET_SIZE (heap )) {
20+ size = PyList_GET_SIZE (heap );
21+ if (pos >= size ) {
2022 PyErr_SetString (PyExc_IndexError , "index out of range" );
2123 return -1 ;
2224 }
@@ -33,12 +35,24 @@ _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
3335 Py_DECREF (newitem );
3436 return -1 ;
3537 }
38+ if (size != PyList_GET_SIZE (heap )) {
39+ Py_DECREF (newitem );
40+ PyErr_SetString (PyExc_RuntimeError ,
41+ "list changed size during iteration" );
42+ return -1 ;
43+ }
3644 if (cmp == 0 )
3745 break ;
3846 Py_INCREF (parent );
39- Py_DECREF ( PyList_GET_ITEM (heap , pos ) );
47+ olditem = PyList_GET_ITEM (heap , pos );
4048 PyList_SET_ITEM (heap , pos , parent );
49+ Py_DECREF (olditem );
4150 pos = parentpos ;
51+ if (size != PyList_GET_SIZE (heap )) {
52+ PyErr_SetString (PyExc_RuntimeError ,
53+ "list changed size during iteration" );
54+ return -1 ;
55+ }
4256 }
4357 Py_DECREF (PyList_GET_ITEM (heap , pos ));
4458 PyList_SET_ITEM (heap , pos , newitem );
@@ -50,10 +64,12 @@ _siftup(PyListObject *heap, Py_ssize_t pos)
5064{
5165 Py_ssize_t startpos , endpos , childpos , rightpos ;
5266 int cmp ;
53- PyObject * newitem , * tmp ;
67+ PyObject * newitem , * tmp , * olditem ;
68+ Py_ssize_t size ;
5469
5570 assert (PyList_Check (heap ));
56- endpos = PyList_GET_SIZE (heap );
71+ size = PyList_GET_SIZE (heap );
72+ endpos = size ;
5773 startpos = pos ;
5874 if (pos >= endpos ) {
5975 PyErr_SetString (PyExc_IndexError , "index out of range" );
@@ -79,13 +95,25 @@ _siftup(PyListObject *heap, Py_ssize_t pos)
7995 if (cmp == 0 )
8096 childpos = rightpos ;
8197 }
98+ if (size != PyList_GET_SIZE (heap )) {
99+ Py_DECREF (newitem );
100+ PyErr_SetString (PyExc_RuntimeError ,
101+ "list changed size during iteration" );
102+ return -1 ;
103+ }
82104 /* Move the smaller child up. */
83105 tmp = PyList_GET_ITEM (heap , childpos );
84106 Py_INCREF (tmp );
85- Py_DECREF ( PyList_GET_ITEM (heap , pos ) );
107+ olditem = PyList_GET_ITEM (heap , pos );
86108 PyList_SET_ITEM (heap , pos , tmp );
109+ Py_DECREF (olditem );
87110 pos = childpos ;
88111 childpos = 2 * pos + 1 ;
112+ if (size != PyList_GET_SIZE (heap )) {
113+ PyErr_SetString (PyExc_RuntimeError ,
114+ "list changed size during iteration" );
115+ return -1 ;
116+ }
89117 }
90118
91119 /* The leaf at pos is empty now. Put newitem there, and and bubble
0 commit comments