Commit ea7f75d4 authored by Tim Peters's avatar Tim Peters

slot_nb_nonzero(): Another leak uncovered by the sandbox datetime

tests.  I found the logic too confusing to follow here, so rewrote more
than was likely absolutely necessary.

Bugfix candidate.
parent 27cae1f7
...@@ -43,7 +43,7 @@ type_name(PyTypeObject *type, void *context) ...@@ -43,7 +43,7 @@ type_name(PyTypeObject *type, void *context)
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
etype* et = (etype*)type; etype* et = (etype*)type;
Py_INCREF(et->name); Py_INCREF(et->name);
return et->name; return et->name;
} }
...@@ -78,7 +78,7 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context) ...@@ -78,7 +78,7 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context)
type->tp_name, value->ob_type->tp_name); type->tp_name, value->ob_type->tp_name);
return -1; return -1;
} }
if (strlen(PyString_AS_STRING(value)) if (strlen(PyString_AS_STRING(value))
!= (size_t)PyString_GET_SIZE(value)) { != (size_t)PyString_GET_SIZE(value)) {
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"__name__ must not contain null bytes"); "__name__ must not contain null bytes");
...@@ -310,10 +310,10 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context) ...@@ -310,10 +310,10 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context)
type->tp_bases = old_bases; type->tp_bases = old_bases;
type->tp_base = old_base; type->tp_base = old_base;
type->tp_mro = old_mro; type->tp_mro = old_mro;
Py_DECREF(value); Py_DECREF(value);
Py_DECREF(new_base); Py_DECREF(new_base);
return -1; return -1;
} }
...@@ -884,21 +884,21 @@ classic_mro(PyObject *cls) ...@@ -884,21 +884,21 @@ classic_mro(PyObject *cls)
return NULL; return NULL;
} }
/* /*
Method resolution order algorithm C3 described in Method resolution order algorithm C3 described in
"A Monotonic Superclass Linearization for Dylan", "A Monotonic Superclass Linearization for Dylan",
by Kim Barrett, Bob Cassel, Paul Haahr, by Kim Barrett, Bob Cassel, Paul Haahr,
David A. Moon, Keith Playford, and P. Tucker Withington. David A. Moon, Keith Playford, and P. Tucker Withington.
(OOPSLA 1996) (OOPSLA 1996)
Some notes about the rules implied by C3: Some notes about the rules implied by C3:
No duplicate bases. No duplicate bases.
It isn't legal to repeat a class in a list of base classes. It isn't legal to repeat a class in a list of base classes.
The next three properties are the 3 constraints in "C3". The next three properties are the 3 constraints in "C3".
Local precendece order. Local precendece order.
If A precedes B in C's MRO, then A will precede B in the MRO of all If A precedes B in C's MRO, then A will precede B in the MRO of all
subclasses of C. subclasses of C.
...@@ -912,7 +912,7 @@ classic_mro(PyObject *cls) ...@@ -912,7 +912,7 @@ classic_mro(PyObject *cls)
the paper for definition of EPG. the paper for definition of EPG.
*/ */
static int static int
tail_contains(PyObject *list, int whence, PyObject *o) { tail_contains(PyObject *list, int whence, PyObject *o) {
int j, size; int j, size;
size = PyList_GET_SIZE(list); size = PyList_GET_SIZE(list);
...@@ -1010,12 +1010,12 @@ set_mro_error(PyObject *to_merge, int *remain) ...@@ -1010,12 +1010,12 @@ set_mro_error(PyObject *to_merge, int *remain)
Py_DECREF(set); Py_DECREF(set);
} }
static int static int
pmerge(PyObject *acc, PyObject* to_merge) { pmerge(PyObject *acc, PyObject* to_merge) {
int i, j, to_merge_size; int i, j, to_merge_size;
int *remain; int *remain;
int ok, empty_cnt; int ok, empty_cnt;
to_merge_size = PyList_GET_SIZE(to_merge); to_merge_size = PyList_GET_SIZE(to_merge);
/* remain stores an index into each sublist of to_merge. /* remain stores an index into each sublist of to_merge.
...@@ -1032,7 +1032,7 @@ pmerge(PyObject *acc, PyObject* to_merge) { ...@@ -1032,7 +1032,7 @@ pmerge(PyObject *acc, PyObject* to_merge) {
empty_cnt = 0; empty_cnt = 0;
for (i = 0; i < to_merge_size; i++) { for (i = 0; i < to_merge_size; i++) {
PyObject *candidate; PyObject *candidate;
PyObject *cur_list = PyList_GET_ITEM(to_merge, i); PyObject *cur_list = PyList_GET_ITEM(to_merge, i);
if (remain[i] >= PyList_GET_SIZE(cur_list)) { if (remain[i] >= PyList_GET_SIZE(cur_list)) {
...@@ -1092,7 +1092,7 @@ mro_implementation(PyTypeObject *type) ...@@ -1092,7 +1092,7 @@ mro_implementation(PyTypeObject *type)
/* Find a superclass linearization that honors the constraints /* Find a superclass linearization that honors the constraints
of the explicit lists of bases and the constraints implied by of the explicit lists of bases and the constraints implied by
each base class. each base class.
to_merge is a list of lists, where each list is a superclass to_merge is a list of lists, where each list is a superclass
linearization implied by a base class. The last element of linearization implied by a base class. The last element of
...@@ -2288,7 +2288,7 @@ compatible_for_assignment(PyTypeObject* old, PyTypeObject* new, char* attr) ...@@ -2288,7 +2288,7 @@ compatible_for_assignment(PyTypeObject* old, PyTypeObject* new, char* attr)
old->tp_name); old->tp_name);
return 0; return 0;
} }
return 1; return 1;
} }
...@@ -2355,7 +2355,7 @@ object_reduce(PyObject *self, PyObject *args) ...@@ -2355,7 +2355,7 @@ object_reduce(PyObject *self, PyObject *args)
} }
static PyMethodDef object_methods[] = { static PyMethodDef object_methods[] = {
{"__reduce__", object_reduce, METH_NOARGS, {"__reduce__", object_reduce, METH_NOARGS,
PyDoc_STR("helper for pickle")}, PyDoc_STR("helper for pickle")},
{0} {0}
}; };
...@@ -3734,30 +3734,29 @@ SLOT0(slot_nb_absolute, "__abs__") ...@@ -3734,30 +3734,29 @@ SLOT0(slot_nb_absolute, "__abs__")
static int static int
slot_nb_nonzero(PyObject *self) slot_nb_nonzero(PyObject *self)
{ {
PyObject *func, *res, *args; PyObject *func, *args;
static PyObject *nonzero_str, *len_str; static PyObject *nonzero_str, *len_str;
int result = -1;
func = lookup_maybe(self, "__nonzero__", &nonzero_str); func = lookup_maybe(self, "__nonzero__", &nonzero_str);
if (func == NULL) { if (func == NULL) {
if (PyErr_Occurred()) if (PyErr_Occurred())
return -1; return -1;
func = lookup_maybe(self, "__len__", &len_str); func = lookup_maybe(self, "__len__", &len_str);
if (func == NULL) { if (func == NULL)
if (PyErr_Occurred()) return PyErr_Occurred() ? -1 : 1;
return -1; }
else args = PyTuple_New(0);
return 1;
}
}
args = res = PyTuple_New(0);
if (args != NULL) { if (args != NULL) {
res = PyObject_Call(func, args, NULL); PyObject *temp = PyObject_Call(func, args, NULL);
Py_DECREF(args); Py_DECREF(args);
if (temp != NULL) {
result = PyObject_IsTrue(temp);
Py_DECREF(temp);
}
} }
Py_DECREF(func); Py_DECREF(func);
if (res == NULL) return result;
return -1;
return PyObject_IsTrue(res);
} }
SLOT0(slot_nb_invert, "__invert__") SLOT0(slot_nb_invert, "__invert__")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment