[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