[Python-checkins] python/dist/src/Objects abstract.c, 2.119,
2.119.12.1
bcannon at users.sourceforge.net
bcannon at users.sourceforge.net
Sat Mar 20 16:54:37 EST 2004
Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5214/Objects
Modified Files:
Tag: release23-maint
abstract.c
Log Message:
Raise RuntimeError if the second argument to isinstance() or issubclass()
is a tuple nested to a depth beyond the interpreter's recursion limit to
prevent a segfault from blowing the C stack.
Fixes bug #858016 .
Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.119
retrieving revision 2.119.12.1
diff -C2 -d -r2.119 -r2.119.12.1
*** abstract.c 1 Mar 2003 01:44:32 -0000 2.119
--- abstract.c 20 Mar 2004 21:54:34 -0000 2.119.12.1
***************
*** 1998,2001 ****
--- 1998,2003 ----
/* Not a general sequence -- that opens up the road to
recursion and stack overflow. */
+ /* XXX: really an issue even though no subsequences get
+ iterated over? */
n = PyTuple_GET_SIZE(cls);
for (i = 0; i < n; i++) {
***************
*** 2036,2041 ****
}
! int
! PyObject_IsInstance(PyObject *inst, PyObject *cls)
{
PyObject *icls;
--- 2038,2043 ----
}
! static int
! recursive_isinstance(PyObject *inst, PyObject *cls, int recursion_depth)
{
PyObject *icls;
***************
*** 2072,2083 ****
}
else if (PyTuple_Check(cls)) {
- /* Not a general sequence -- that opens up the road to
- recursion and stack overflow. */
int i, n;
n = PyTuple_GET_SIZE(cls);
for (i = 0; i < n; i++) {
! retval = PyObject_IsInstance(
! inst, PyTuple_GET_ITEM(cls, i));
if (retval != 0)
break;
--- 2074,2091 ----
}
else if (PyTuple_Check(cls)) {
int i, n;
+ if (!recursion_depth) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Recursion depth exceeded");
+ return NULL;
+ }
+
n = PyTuple_GET_SIZE(cls);
for (i = 0; i < n; i++) {
! retval = recursive_isinstance(
! inst,
! PyTuple_GET_ITEM(cls, i),
! recursion_depth-1);
if (retval != 0)
break;
***************
*** 2103,2108 ****
}
int
! PyObject_IsSubclass(PyObject *derived, PyObject *cls)
{
int retval;
--- 2111,2127 ----
}
+ /* Use recursive_isinstance to have a hard limit on the depth of the possible
+ tuple second argument.
+
+ Done to prevent segfaulting by blowing the C stack.
+ */
int
! PyObject_IsInstance(PyObject *inst, PyObject *cls)
! {
! return recursive_isinstance(inst, cls, Py_GetRecursionLimit());
! }
!
! static int
! recursive_issubclass(PyObject *derived, PyObject *cls, int recursion_depth)
{
int retval;
***************
*** 2116,2122 ****
int i;
int n = PyTuple_GET_SIZE(cls);
for (i = 0; i < n; ++i) {
! retval = PyObject_IsSubclass(
! derived, PyTuple_GET_ITEM(cls, i));
if (retval != 0) {
/* either found it, or got an error */
--- 2135,2150 ----
int i;
int n = PyTuple_GET_SIZE(cls);
+
+ if (!recursion_depth) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Recursion depth exceeded");
+ return NULL;
+ }
+
for (i = 0; i < n; ++i) {
! retval = recursive_issubclass(
! derived,
! PyTuple_GET_ITEM(cls, i),
! recursion_depth-1);
if (retval != 0) {
/* either found it, or got an error */
***************
*** 2144,2147 ****
--- 2172,2186 ----
}
+ /* Use recursive_issubclass to have a hard limit on the depth of the possible
+ tuple second argument.
+
+ Done to prevent segfaulting by blowing the C stack.
+ */
+ int
+ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+ {
+ return recursive_issubclass(derived, cls, Py_GetRecursionLimit());
+ }
+
PyObject *
PyObject_GetIter(PyObject *o)
More information about the Python-checkins
mailing list