From 5a79d2ae572fed03eb9b9554b2760a34e75191a7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 4 Sep 2023 11:21:47 +0200 Subject: [PATCH] =?UTF-8?q?Revert=20"gh-46376:=20Return=20existing=20point?= =?UTF-8?q?er=20when=20possible=20in=20ctypes=20(#1=E2=80=A6=20(#108688)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 08447b5deb47e2a0df87fa0a0576d300e5c909b4. Revert also _ctypes.c changes of the PyDict_ContainsString() change, commit 67266266469fe0e817736227f39537182534c1a5. --- Lib/test/test_ctypes/test_keeprefs.py | 27 -------------- ...3-07-24-01-21-16.gh-issue-46376.w-xuDL.rst | 1 - Modules/_ctypes/_ctypes.c | 35 ------------------- 3 files changed, 63 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2023-07-24-01-21-16.gh-issue-46376.w-xuDL.rst diff --git a/Lib/test/test_ctypes/test_keeprefs.py b/Lib/test/test_ctypes/test_keeprefs.py index c6fe1de62ea..23b03b64b4a 100644 --- a/Lib/test/test_ctypes/test_keeprefs.py +++ b/Lib/test/test_ctypes/test_keeprefs.py @@ -98,33 +98,6 @@ class PointerTestCase(unittest.TestCase): x = pointer(i) self.assertEqual(x._objects, {'1': i}) - def test_pp_ownership(self): - d = c_int(123) - n = c_int(456) - - p = pointer(d) - pp = pointer(p) - - self.assertIs(pp._objects['1'], p) - self.assertIs(pp._objects['0']['1'], d) - - pp.contents.contents = n - - self.assertIs(pp._objects['1'], p) - self.assertIs(pp._objects['0']['1'], n) - - self.assertIs(p._objects['1'], n) - self.assertEqual(len(p._objects), 1) - - del d - del p - - self.assertIs(pp._objects['0']['1'], n) - self.assertEqual(len(pp._objects), 2) - - del n - - self.assertEqual(len(pp._objects), 2) class PointerToStructure(unittest.TestCase): def test(self): diff --git a/Misc/NEWS.d/next/Library/2023-07-24-01-21-16.gh-issue-46376.w-xuDL.rst b/Misc/NEWS.d/next/Library/2023-07-24-01-21-16.gh-issue-46376.w-xuDL.rst deleted file mode 100644 index 8e8f0245b45..00000000000 --- a/Misc/NEWS.d/next/Library/2023-07-24-01-21-16.gh-issue-46376.w-xuDL.rst +++ /dev/null @@ -1 +0,0 @@ -Prevent memory leak and use-after-free when using pointers to pointers with ctypes diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index ed9efcad9ab..3af3a80bfb5 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -5148,41 +5148,6 @@ Pointer_get_contents(CDataObject *self, void *closure) stgdict = PyObject_stgdict((PyObject *)self); assert(stgdict); /* Cannot be NULL for pointer instances */ - - PyObject *keep = GetKeepedObjects(self); - if (keep != NULL) { - // check if it's a pointer to a pointer: - // pointers will have '0' key in the _objects - int ptr_probe = PyDict_ContainsString(keep, "0"); - if (ptr_probe < 0) { - return NULL; - } - if (ptr_probe) { - PyObject *item; - if (PyDict_GetItemStringRef(keep, "1", &item) < 0) { - return NULL; - } - if (item == NULL) { - PyErr_SetString(PyExc_ValueError, - "Unexpected NULL pointer in _objects"); - return NULL; - } -#ifndef NDEBUG - CDataObject *ptr2ptr = (CDataObject *)item; - // Don't construct a new object, - // return existing one instead to preserve refcount. - // Double-check that we are returning the same thing. - assert( - *(void**) self->b_ptr == ptr2ptr->b_ptr || - *(void**) self->b_value.c == ptr2ptr->b_ptr || - *(void**) self->b_ptr == ptr2ptr->b_value.c || - *(void**) self->b_value.c == ptr2ptr->b_value.c - ); -#endif - return item; - } - } - return PyCData_FromBaseObj(stgdict->proto, (PyObject *)self, 0, *(void **)self->b_ptr);