]> granicus.if.org Git - python/commitdiff
bpo-38150 Fix refleak in the finalizer of a _testcapimodule type (GH-16115)
authorEddie Elizondo <eelizondo@fb.com>
Fri, 13 Sep 2019 16:48:03 +0000 (12:48 -0400)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 13 Sep 2019 16:48:03 +0000 (09:48 -0700)
The PyLong created in the finalizer was not being cleaned up

https://bugs.python.org/issue38150

Automerge-Triggered-By: @matrixise
Modules/_testcapimodule.c

index dee06de107a1a3c95d3f0b615296ec76ee6124b4..4cca784d0148d306c633b59fda43d86ba2d7e289 100644 (file)
@@ -6304,7 +6304,7 @@ static void
 heapctypesubclasswithfinalizer_finalize(PyObject *self)
 {
     PyObject *error_type, *error_value, *error_traceback, *m;
-    PyObject *oldtype = NULL, *newtype = NULL;
+    PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL;
 
     /* Save the current exception, if any. */
     PyErr_Fetch(&error_type, &error_value, &error_traceback);
@@ -6322,18 +6322,26 @@ heapctypesubclasswithfinalizer_finalize(PyObject *self)
     if (PyObject_SetAttrString(self, "__class__", newtype) < 0) {
         goto cleanup_finalize;
     }
-    if (PyObject_SetAttrString(
-        oldtype, "refcnt_in_del", PyLong_FromSsize_t(Py_REFCNT(oldtype))) < 0) {
+    refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype));
+    if (refcnt == NULL) {
         goto cleanup_finalize;
     }
-    if (PyObject_SetAttrString(
-        newtype, "refcnt_in_del", PyLong_FromSsize_t(Py_REFCNT(newtype))) < 0) {
+    if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) {
+        goto cleanup_finalize;
+    }
+    Py_DECREF(refcnt);
+    refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype));
+    if (refcnt == NULL) {
+        goto cleanup_finalize;
+    }
+    if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) {
         goto cleanup_finalize;
     }
 
 cleanup_finalize:
     Py_XDECREF(oldtype);
     Py_XDECREF(newtype);
+    Py_XDECREF(refcnt);
 
     /* Restore the saved exception. */
     PyErr_Restore(error_type, error_value, error_traceback);