From 2178bbc12195104e94995ec075ad5f7c69d1ec78 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 21 Jun 2023 16:35:41 +0200 Subject: [PATCH] gh-105927: Fix test_weakref_capi() refleak (#105966) Test PyWeakref_GetRef(NULL) and PyWeakref_GetObject(NULL). --- Modules/_testcapimodule.c | 48 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 8b63f9c90a3..d847539f660 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3395,27 +3395,29 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) Py_DECREF(obj); return NULL; } + + // test PyWeakref_Check(), valid weakref object assert(PyWeakref_Check(weakref)); assert(PyWeakref_CheckRefExact(weakref)); assert(PyWeakref_CheckRefExact(weakref)); assert(Py_REFCNT(obj) == refcnt); // test PyWeakref_GetRef(), reference is alive - PyObject *ref1; - assert(PyWeakref_GetRef(weakref, &ref1) == 0); - assert(ref1 == obj); + PyObject *ref = Py_True; // marker to check that value was set + assert(PyWeakref_GetRef(weakref, &ref) == 0); + assert(ref == obj); assert(Py_REFCNT(obj) == (refcnt + 1)); - Py_DECREF(ref1); + Py_DECREF(ref); // test PyWeakref_GetObject(), reference is alive - PyObject *ref2 = PyWeakref_GetObject(weakref); - assert(ref2 == obj); + ref = PyWeakref_GetObject(weakref); // borrowed ref + assert(ref == obj); // test PyWeakref_GET_OBJECT(), reference is alive - PyObject *ref3 = PyWeakref_GET_OBJECT(weakref); - assert(ref3 == obj); + ref = PyWeakref_GET_OBJECT(weakref); // borrowed ref + assert(ref == obj); - // delete the referenced object + // delete the referenced object: clear the weakref assert(Py_REFCNT(obj) == 1); Py_DECREF(obj); @@ -3423,11 +3425,11 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) assert(PyWeakref_GET_OBJECT(weakref) == Py_None); // test PyWeakref_GetRef(), reference is dead - PyObject *ref4 = Py_True; // marker to check that value was set - assert(PyWeakref_GetRef(weakref, &ref4) == 0); - assert(ref4 == NULL); + ref = Py_True; + assert(PyWeakref_GetRef(weakref, &ref) == 0); + assert(ref == NULL); - // None is not a weak reference object + // test PyWeakref_Check(), not a weakref object PyObject *invalid_weakref = Py_None; assert(!PyWeakref_Check(invalid_weakref)); assert(!PyWeakref_CheckRefExact(invalid_weakref)); @@ -3435,17 +3437,31 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) // test PyWeakref_GetRef(), invalid type assert(!PyErr_Occurred()); - PyObject *ref5 = Py_True; // marker to check that value was set - assert(PyWeakref_GetRef(invalid_weakref, &ref5) == -1); + ref = Py_True; + assert(PyWeakref_GetRef(invalid_weakref, &ref) == -1); assert(PyErr_ExceptionMatches(PyExc_TypeError)); PyErr_Clear(); - assert(ref5 == NULL); + assert(ref == NULL); // test PyWeakref_GetObject(), invalid type assert(PyWeakref_GetObject(invalid_weakref) == NULL); assert(PyErr_ExceptionMatches(PyExc_SystemError)); PyErr_Clear(); + // test PyWeakref_GetRef(NULL) + ref = Py_True; // marker to check that value was set + assert(PyWeakref_GetRef(NULL, &ref) == -1); + assert(PyErr_ExceptionMatches(PyExc_SystemError)); + assert(ref == NULL); + PyErr_Clear(); + + // test PyWeakref_GetObject(NULL) + assert(PyWeakref_GetObject(NULL) == NULL); + assert(PyErr_ExceptionMatches(PyExc_SystemError)); + PyErr_Clear(); + + Py_DECREF(weakref); + Py_RETURN_NONE; }