[Python-checkins] CVS: python/dist/src/Objects weakrefobject.c,1.1,1.2

Fred L. Drake fdrake@users.sourceforge.net
Thu, 18 Oct 2001 11:04:20 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv32253/Objects

Modified Files:
	weakrefobject.c 
Log Message:
When weakref proxies are involved in binary & ternary slot operations,
the left-hand operand may not be the proxy in all cases.  If it isn't,
we end up doing two things: a) unwrapping something that isn't a
PyWeakReference (later resulting in a core dump) and b) passing a
proxy as the right-hand operand anyway, even though that can't be
handled by the actual handler (maybe eventually causing a core dump).

This is fixed by always unwrapping all the proxies involved before
passing anything to the actual handler.


Index: weakrefobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** weakrefobject.c	2001/10/05 21:52:26	1.1
--- weakrefobject.c	2001/10/18 18:04:18	1.2
***************
*** 208,236 ****
  
  
  #define WRAP_UNARY(method, generic) \
      static PyObject * \
!     method(PyWeakReference *proxy) { \
!         if (!proxy_checkref(proxy)) { \
!             return NULL; \
!         } \
!         return generic(PyWeakref_GET_OBJECT(proxy)); \
      }
  
  #define WRAP_BINARY(method, generic) \
      static PyObject * \
!     method(PyWeakReference *proxy, PyObject *v) { \
!         if (!proxy_checkref(proxy)) { \
!             return NULL; \
!         } \
!         return generic(PyWeakref_GET_OBJECT(proxy), v); \
      }
  
  #define WRAP_TERNARY(method, generic) \
      static PyObject * \
!     method(PyWeakReference *proxy, PyObject *v, PyObject *w) { \
!         if (!proxy_checkref(proxy)) { \
!             return NULL; \
! 	} \
!         return generic(PyWeakref_GET_OBJECT(proxy), v, w); \
      }
  
--- 208,249 ----
  
  
+ /* If a parameter is a proxy, check that it is still "live" and wrap it,
+  * replacing the original value with the raw object.  Raises ReferenceError
+  * if the param is a dead proxy.
+  */
+ #define UNWRAP(o) \
+         if (PyWeakref_CheckProxy(o)) { \
+             if (!proxy_checkref((PyWeakReference *)o)) \
+                 return NULL; \
+             o = PyWeakref_GET_OBJECT(o); \
+         }
+ 
  #define WRAP_UNARY(method, generic) \
      static PyObject * \
!     method(PyObject *proxy) { \
!         UNWRAP(proxy); \
!         return generic(proxy); \
      }
  
  #define WRAP_BINARY(method, generic) \
      static PyObject * \
!     method(PyObject *x, PyObject *y) { \
!         UNWRAP(x); \
!         UNWRAP(y); \
!         return generic(x, y); \
      }
  
+ /* Note that the second and third args need to be checked for NULL since
+  * (at least) the tp_call slot can receive NULL for either of those args.
+  */
  #define WRAP_TERNARY(method, generic) \
      static PyObject * \
!     method(PyObject *proxy, PyObject *v, PyObject *w) { \
!         UNWRAP(proxy); \
!         if (v != NULL) \
!             UNWRAP(v); \
!         if (w != NULL) \
!             UNWRAP(w); \
!         return generic(proxy, v, w); \
      }