[Python-bugs-list] BUG: classobject.c (PR#98)

guido@cnri.reston.va.us guido@cnri.reston.va.us
Mon, 11 Oct 1999 08:41:44 -0400 (EDT)


> 3 lines starting at 1554:
> 		funcname = PyObject_GetAttrString(func,"__name__");
> 		if (funcname == NULL)
> 			PyErr_Clear();
> 
> should be (perhaps - not sure if this will leak or not):
> 		funcname = PyObject_GetAttrString(func,"__name__");
> 		if (funcname == NULL)
> 			PyErr_Clear();
> 		else
> 			Py_INCREF(funcname);
> 
> or else - line 1562:
> 	Py_XDECREF(funcname);
> 
> causes an free'd memory read (fname) at line 1567:
> 	if (self == NULL)
> 		sprintf(buf, "<unbound method %.100s.%.100s>", fcname, fname);

Almost.  The PyObject_GetAttrString() call increfs the object, but if
the refcnt is 1, the fname variable can point to freed memory because
the object is decrefed before it is used.

I think that the proper fix is to move the Py_XDECREF() call down
towards the end of the function, as follows:

Index: classobject.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/classobject.c,v
retrieving revision 2.80
diff -c -r2.80 classobject.c
*** classobject.c	1998/08/04 14:59:16	2.80
--- classobject.c	1999/10/10 21:21:26
***************
*** 1559,1565 ****
  		fname = PyString_AS_STRING(funcname);
  	else
  		fname = "?";
- 	Py_XDECREF(funcname);
  	if (fclassname != NULL && PyString_Check(fclassname))
  		fcname = PyString_AsString(fclassname);
  	else
--- 1559,1564 ----
***************
*** 1575,1580 ****
--- 1574,1580 ----
  		sprintf(buf, "<method %.60s.%.60s of %.60s instance at %lx>",
  			fcname, fname, icname, (long)self);
  	}
+ 	Py_XDECREF(funcname);
  	return PyString_FromString(buf);
  }
  
Can you try this?  (I don't have a testcase that exposes this bug; do
you?)

Please let me know so I can check in the fix.

--Guido van Rossum (home page: http://www.python.org/~guido/)