diff options
author | Brett Cannon <bcannon@gmail.com> | 2004-03-20 22:52:14 (GMT) |
---|---|---|
committer | Brett Cannon <bcannon@gmail.com> | 2004-03-20 22:52:14 (GMT) |
commit | 4f65331483197a9909b19694688c55fdf9ca7a37 (patch) | |
tree | 1d8dae183e1f6528ca75c85082c4eeb8a4e8a803 /Objects/abstract.c | |
parent | c69661725a9d505d8f33a4a220d5489cb1de750f (diff) | |
download | cpython-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.c | 45 |
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) { |