]> granicus.if.org Git - python/commitdiff
[3.8] bpo-38150: Fix refleak in the finalizer of a _testcapimodule type (GH-16115...
authorStéphane Wirtel <stephane@wirtel.be>
Fri, 13 Sep 2019 17:10:53 +0000 (18:10 +0100)
committerGitHub <noreply@github.com>
Fri, 13 Sep 2019 17:10:53 +0000 (18:10 +0100)
The PyLong created in the finalizer was not being cleaned up

https://bugs.python.org/issue38150

Automerge-Triggered-By: @matrixise
(cherry picked from commit a67ac2f2d9550e5a36d28f9b6eeacf6575dda2d5)

Co-authored-by: Eddie Elizondo <eelizondo@fb.com>
Modules/_testcapimodule.c

index cb9206ca4eba5ae8b722a3716a457ca94063ae4f..cccf9249040dfcc934bf68cd1b7309f4d12cc72f 100644 (file)
@@ -6090,7 +6090,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);
@@ -6108,18 +6108,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);