Skip to content

Commit cdc6515

Browse files
gh-156124: Fix a crash when deleting ctypes Pointer.contents
In the free-threaded build the setter passed the value to Py_BEGIN_CRITICAL_SECTION2() before checking it for NULL.
1 parent 228b1bf commit cdc6515

3 files changed

Lines changed: 13 additions & 6 deletions

File tree

Lib/test/test_ctypes/test_delattr.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import unittest
2-
from ctypes import Structure, c_char, c_int
2+
from ctypes import POINTER, Structure, c_char, c_int
33

44

55
class X(Structure):
@@ -16,6 +16,11 @@ def test_chararray(self):
1616
with self.assertRaises(TypeError):
1717
del chararray.value
1818

19+
def test_pointer_contents(self):
20+
ptr = POINTER(c_int)(c_int(42))
21+
with self.assertRaises(TypeError):
22+
del ptr.contents
23+
1924
def test_struct(self):
2025
struct = X()
2126
with self.assertRaises(TypeError):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a crash in the free-threaded build when deleting the :attr:`!contents`
2+
attribute of a :mod:`ctypes` pointer.

Modules/_ctypes/_ctypes.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5713,11 +5713,6 @@ Pointer_set_contents_lock_held(PyObject *op, PyObject *value, void *closure)
57135713
PyObject *keep;
57145714
CDataObject *self = _CDataObject_CAST(op);
57155715

5716-
if (value == NULL) {
5717-
PyErr_SetString(PyExc_TypeError,
5718-
"Pointer does not support item deletion");
5719-
return -1;
5720-
}
57215716
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
57225717
StgInfo *stginfo;
57235718
if (PyStgInfo_FromObject(st, op, &stginfo) < 0) {
@@ -5761,6 +5756,11 @@ Pointer_set_contents_lock_held(PyObject *op, PyObject *value, void *closure)
57615756
static int
57625757
Pointer_set_contents(PyObject *op, PyObject *value, void *closure)
57635758
{
5759+
if (value == NULL) {
5760+
PyErr_SetString(PyExc_TypeError,
5761+
"Pointer does not support item deletion");
5762+
return -1;
5763+
}
57645764
int res;
57655765
Py_BEGIN_CRITICAL_SECTION2(op, value);
57665766
res = Pointer_set_contents_lock_held(op, value, closure);

0 commit comments

Comments
 (0)