[Python-checkins] python/dist/src/Objects listobject.c,2.166,2.167
mwh at users.sourceforge.net
mwh at users.sourceforge.net
Thu Dec 4 06:25:48 EST 2003
Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv21077/Objects
Modified Files:
listobject.c
Log Message:
Fixes and tests for various "holding pointers when arbitrary Python code
can run" bugs as discussed in
[ 848856 ] couple of new list.sort bugs
Index: listobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v
retrieving revision 2.166
retrieving revision 2.167
diff -C2 -d -r2.166 -r2.167
*** listobject.c 28 Nov 2003 21:43:02 -0000 2.166
--- listobject.c 4 Dec 2003 11:25:46 -0000 2.167
***************
*** 1849,1853 ****
int reverse = 0;
PyObject *keyfunc = NULL;
! int i, len = 0;
PyObject *key, *value, *kvpair;
static char *kwlist[] = {"cmp", "key", "reverse", 0};
--- 1849,1853 ----
int reverse = 0;
PyObject *keyfunc = NULL;
! int i;
PyObject *key, *value, *kvpair;
static char *kwlist[] = {"cmp", "key", "reverse", 0};
***************
*** 1871,1887 ****
Py_XINCREF(compare);
if (keyfunc != NULL) {
! len = PyList_GET_SIZE(self);
! for (i=0 ; i < len ; i++) {
! value = PyList_GET_ITEM(self, i);
key = PyObject_CallFunctionObjArgs(keyfunc, value,
NULL);
if (key == NULL) {
for (i=i-1 ; i>=0 ; i--) {
! kvpair = PyList_GET_ITEM(self, i);
value = sortwrapper_getvalue(kvpair);
! PyList_SET_ITEM(self, i, value);
Py_DECREF(kvpair);
}
goto dsu_fail;
}
--- 1871,1908 ----
Py_XINCREF(compare);
+ /* The list is temporarily made empty, so that mutations performed
+ * by comparison functions can't affect the slice of memory we're
+ * sorting (allowing mutations during sorting is a core-dump
+ * factory, since ob_item may change).
+ */
+ saved_ob_size = self->ob_size;
+ saved_ob_item = self->ob_item;
+ self->ob_size = 0;
+ self->ob_item = empty_ob_item = PyMem_NEW(PyObject *, 0);
+
if (keyfunc != NULL) {
! for (i=0 ; i < saved_ob_size ; i++) {
! value = saved_ob_item[i];
key = PyObject_CallFunctionObjArgs(keyfunc, value,
NULL);
if (key == NULL) {
for (i=i-1 ; i>=0 ; i--) {
! kvpair = saved_ob_item[i];
value = sortwrapper_getvalue(kvpair);
! saved_ob_item[i] = value;
Py_DECREF(kvpair);
}
+ if (self->ob_item != empty_ob_item
+ || self->ob_size) {
+ /* If the list changed *as well* we
+ have two errors. We let the first
+ one "win", but we shouldn't let
+ what's in the list currently
+ leak. */
+ (void)list_ass_slice(
+ self, 0, self->ob_size,
+ (PyObject *)NULL);
+ }
+
goto dsu_fail;
}
***************
*** 1889,1893 ****
if (kvpair == NULL)
goto dsu_fail;
! PyList_SET_ITEM(self, i, kvpair);
}
}
--- 1910,1914 ----
if (kvpair == NULL)
goto dsu_fail;
! saved_ob_item[i] = kvpair;
}
}
***************
*** 1895,1913 ****
/* Reverse sort stability achieved by initially reversing the list,
applying a stable forward sort, then reversing the final result. */
! if (reverse && self->ob_size > 1)
! reverse_slice(self->ob_item, self->ob_item + self->ob_size);
merge_init(&ms, compare);
- /* The list is temporarily made empty, so that mutations performed
- * by comparison functions can't affect the slice of memory we're
- * sorting (allowing mutations during sorting is a core-dump
- * factory, since ob_item may change).
- */
- saved_ob_size = self->ob_size;
- saved_ob_item = self->ob_item;
- self->ob_size = 0;
- self->ob_item = empty_ob_item = PyMem_NEW(PyObject *, 0);
-
nremaining = saved_ob_size;
if (nremaining < 2)
--- 1916,1924 ----
/* Reverse sort stability achieved by initially reversing the list,
applying a stable forward sort, then reversing the final result. */
! if (reverse && saved_ob_size > 1)
! reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
merge_init(&ms, compare);
nremaining = saved_ob_size;
if (nremaining < 2)
***************
*** 1960,1963 ****
--- 1971,1983 ----
result = Py_None;
fail:
+ if (keyfunc != NULL) {
+ for (i=0 ; i < saved_ob_size ; i++) {
+ kvpair = saved_ob_item[i];
+ value = sortwrapper_getvalue(kvpair);
+ saved_ob_item[i] = value;
+ Py_DECREF(kvpair);
+ }
+ }
+
if (self->ob_item != empty_ob_item || self->ob_size) {
/* The user mucked with the list during the sort. */
***************
*** 1969,1992 ****
}
}
- if (self->ob_item == empty_ob_item)
- PyMem_FREE(empty_ob_item);
- self->ob_size = saved_ob_size;
- self->ob_item = saved_ob_item;
- merge_freemem(&ms);
! if (keyfunc != NULL) {
! len = PyList_GET_SIZE(self);
! for (i=0 ; i < len ; i++) {
! kvpair = PyList_GET_ITEM(self, i);
! value = sortwrapper_getvalue(kvpair);
! PyList_SET_ITEM(self, i, value);
! Py_DECREF(kvpair);
! }
! }
! if (reverse && self->ob_size > 1)
! reverse_slice(self->ob_item, self->ob_item + self->ob_size);
dsu_fail:
Py_XDECREF(compare);
Py_XINCREF(result);
--- 1989,2003 ----
}
}
! if (reverse && saved_ob_size > 1)
! reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
! merge_freemem(&ms);
dsu_fail:
+ if (self->ob_item == empty_ob_item)
+ PyMem_FREE(empty_ob_item);
+ self->ob_size = saved_ob_size;
+ self->ob_item = saved_ob_item;
Py_XDECREF(compare);
Py_XINCREF(result);
More information about the Python-checkins
mailing list