Kaydet (Commit) 73006d02 authored tarafından Fred Drake's avatar Fred Drake

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.
üst a5343ccd
...@@ -207,31 +207,44 @@ proxy_checkref(PyWeakReference *proxy) ...@@ -207,31 +207,44 @@ proxy_checkref(PyWeakReference *proxy)
} }
/* 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) \ #define WRAP_UNARY(method, generic) \
static PyObject * \ static PyObject * \
method(PyWeakReference *proxy) { \ method(PyObject *proxy) { \
if (!proxy_checkref(proxy)) { \ UNWRAP(proxy); \
return NULL; \ return generic(proxy); \
} \
return generic(PyWeakref_GET_OBJECT(proxy)); \
} }
#define WRAP_BINARY(method, generic) \ #define WRAP_BINARY(method, generic) \
static PyObject * \ static PyObject * \
method(PyWeakReference *proxy, PyObject *v) { \ method(PyObject *x, PyObject *y) { \
if (!proxy_checkref(proxy)) { \ UNWRAP(x); \
return NULL; \ UNWRAP(y); \
} \ return generic(x, y); \
return generic(PyWeakref_GET_OBJECT(proxy), v); \
} }
/* 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) \ #define WRAP_TERNARY(method, generic) \
static PyObject * \ static PyObject * \
method(PyWeakReference *proxy, PyObject *v, PyObject *w) { \ method(PyObject *proxy, PyObject *v, PyObject *w) { \
if (!proxy_checkref(proxy)) { \ UNWRAP(proxy); \
return NULL; \ if (v != NULL) \
} \ UNWRAP(v); \
return generic(PyWeakref_GET_OBJECT(proxy), v, w); \ if (w != NULL) \
UNWRAP(w); \
return generic(proxy, v, w); \
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment