mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
fix reentrancy bug in slice assignment
This commit is contained in:
parent
ba0b6aeda6
commit
ae7bf1a5e7
1 changed files with 20 additions and 4 deletions
|
@ -368,6 +368,13 @@ list_ass_slice(a, ilow, ihigh, v)
|
|||
int ilow, ihigh;
|
||||
object *v;
|
||||
{
|
||||
/* Because [X]DECREF can recursively invoke list operations on
|
||||
this list, we must postpone all [X]DECREF activity until
|
||||
after the list is back in its canonical shape. Therefore
|
||||
we must allocate an additional array, 'recycle', into which
|
||||
we temporarily copy the items that are deleted from the
|
||||
list. :-( */
|
||||
object **recycle, **p;
|
||||
object **item;
|
||||
int n; /* Size of replacement list */
|
||||
int d; /* Change in size */
|
||||
|
@ -402,9 +409,13 @@ list_ass_slice(a, ilow, ihigh, v)
|
|||
ihigh = a->ob_size;
|
||||
item = a->ob_item;
|
||||
d = n - (ihigh-ilow);
|
||||
if (d <= 0) { /* Delete -d items; XDECREF ihigh-ilow items */
|
||||
if (ihigh > ilow)
|
||||
p = recycle = NEW(object *, (ihigh-ilow));
|
||||
else
|
||||
p = recycle = NULL;
|
||||
if (d <= 0) { /* Delete -d items; recycle ihigh-ilow items */
|
||||
for (k = ilow; k < ihigh; k++)
|
||||
XDECREF(item[k]); /* bug: reentrant side effects */
|
||||
*p++ = item[k];
|
||||
if (d < 0) {
|
||||
for (/*k = ihigh*/; k < a->ob_size; k++)
|
||||
item[k+d] = item[k];
|
||||
|
@ -413,7 +424,7 @@ list_ass_slice(a, ilow, ihigh, v)
|
|||
a->ob_item = item;
|
||||
}
|
||||
}
|
||||
else { /* Insert d items; XDECREF ihigh-ilow items */
|
||||
else { /* Insert d items; recycle ihigh-ilow items */
|
||||
RESIZE(item, object *, a->ob_size + d);
|
||||
if (item == NULL) {
|
||||
err_nomem();
|
||||
|
@ -422,7 +433,7 @@ list_ass_slice(a, ilow, ihigh, v)
|
|||
for (k = a->ob_size; --k >= ihigh; )
|
||||
item[k+d] = item[k];
|
||||
for (/*k = ihigh-1*/; k >= ilow; --k)
|
||||
XDECREF(item[k]); /* bug: side effects :-( */
|
||||
*p++ = item[k];
|
||||
a->ob_item = item;
|
||||
a->ob_size += d;
|
||||
}
|
||||
|
@ -431,6 +442,11 @@ list_ass_slice(a, ilow, ihigh, v)
|
|||
XINCREF(w);
|
||||
item[ilow] = w;
|
||||
}
|
||||
if (recycle) {
|
||||
while (--p >= recycle)
|
||||
XDECREF(*p);
|
||||
DEL(recycle);
|
||||
}
|
||||
return 0;
|
||||
#undef b
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue