summaryrefslogtreecommitdiffstats
path: root/Objects/abstract.c
diff options
context:
space:
mode:
authorBrett Cannon <bcannon@gmail.com>2004-03-20 22:52:14 (GMT)
committerBrett Cannon <bcannon@gmail.com>2004-03-20 22:52:14 (GMT)
commit4f65331483197a9909b19694688c55fdf9ca7a37 (patch)
tree1d8dae183e1f6528ca75c85082c4eeb8a4e8a803 /Objects/abstract.c
parentc69661725a9d505d8f33a4a220d5489cb1de750f (diff)
downloadcpython-4f65331483197a9909b19694688c55fdf9ca7a37.zip
cpython-4f65331483197a9909b19694688c55fdf9ca7a37.tar.gz
cpython-4f65331483197a9909b19694688c55fdf9ca7a37.tar.bz2
Limit the nesting depth of a tuple passed as the second argument to
isinstance() or issubclass() to the recursion limit of the interpreter.
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r--Objects/abstract.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 060abc5..3d6d829 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1992,8 +1992,8 @@ check_class(PyObject *cls, const char *error)
return -1;
}
-int
-PyObject_IsInstance(PyObject *inst, PyObject *cls)
+static int
+recursive_isinstance(PyObject *inst, PyObject *cls, int recursion_depth)
{
PyObject *icls;
static PyObject *__class__ = NULL;
@@ -2028,14 +2028,20 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
}
}
else if (PyTuple_Check(cls)) {
- /* Not a general sequence -- that opens up the road to
- recursion and stack overflow. */
int i, n;
+ if (!recursion_depth) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "nest level of tuple too deep");
+ return NULL;
+ }
+
n = PyTuple_GET_SIZE(cls);
for (i = 0; i < n; i++) {
- retval = PyObject_IsInstance(
- inst, PyTuple_GET_ITEM(cls, i));
+ retval = recursive_isinstance(
+ inst,
+ PyTuple_GET_ITEM(cls, i),
+ recursion_depth-1);
if (retval != 0)
break;
}
@@ -2060,7 +2066,13 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
}
int
-PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+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;
@@ -2072,9 +2084,17 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
if (PyTuple_Check(cls)) {
int i;
int n = PyTuple_GET_SIZE(cls);
+
+ if (!recursion_depth) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "nest level of tuple too deep");
+ return NULL;
+ }
for (i = 0; i < n; ++i) {
- retval = PyObject_IsSubclass(
- derived, PyTuple_GET_ITEM(cls, i));
+ retval = recursive_issubclass(
+ derived,
+ PyTuple_GET_ITEM(cls, i),
+ recursion_depth-1);
if (retval != 0) {
/* either found it, or got an error */
return retval;
@@ -2100,6 +2120,13 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
return retval;
}
+int
+PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+{
+ return recursive_issubclass(derived, cls, Py_GetRecursionLimit());
+}
+
+
PyObject *
PyObject_GetIter(PyObject *o)
{