]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-128182: add critical section to `_ctypes.PyCData` methods (#132082)
authorKumar Aditya <kumaraditya@python.org>
Sat, 5 Apr 2025 09:54:58 +0000 (15:24 +0530)
committerGitHub <noreply@github.com>
Sat, 5 Apr 2025 09:54:58 +0000 (15:24 +0530)
Modules/_ctypes/_ctypes.c
Modules/_ctypes/clinic/_ctypes.c.h

index efefc0157237bdf0c3874708ab13115a8dc05e68..d6bcaa2c7aa9583cffee12ee5cc4be0c403176b9 100644 (file)
@@ -3007,7 +3007,8 @@ PyCData_nohash(PyObject *self)
 }
 
 /*[clinic input]
-_ctypes.PyCData.__reduce__ as PyCData_reduce
+@critical_section
+_ctypes.PyCData.__reduce__
 
     myself: self
     cls: defining_class
@@ -3015,8 +3016,8 @@ _ctypes.PyCData.__reduce__ as PyCData_reduce
 [clinic start generated code]*/
 
 static PyObject *
-PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls)
-/*[clinic end generated code: output=1a025ccfdd8c935d input=34097a5226ea63c1]*/
+_ctypes_PyCData___reduce___impl(PyObject *myself, PyTypeObject *cls)
+/*[clinic end generated code: output=eaad97e111599294 input=6a464e1a1e2bbdbd]*/
 {
     CDataObject *self = _CDataObject_CAST(myself);
 
@@ -3037,33 +3038,33 @@ PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls)
         return NULL;
     }
     PyObject *bytes;
-    LOCK_PTR(self);
     bytes = PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
-    UNLOCK_PTR(self);
     return Py_BuildValue("O(O(NN))", st->_unpickle, Py_TYPE(myself), dict,
                          bytes);
 }
 
+/*[clinic input]
+@critical_section
+_ctypes.PyCData.__setstate__
+
+    myself: self
+    dict: object(subclass_of="&PyDict_Type")
+    data: str(accept={str, robuffer}, zeroes=True)
+    /
+[clinic start generated code]*/
+
 static PyObject *
-PyCData_setstate(PyObject *myself, PyObject *args)
+_ctypes_PyCData___setstate___impl(PyObject *myself, PyObject *dict,
+                                  const char *data, Py_ssize_t data_length)
+/*[clinic end generated code: output=8bd4c0a5b4f254bd input=124f5070258254c6]*/
 {
-    void *data;
-    Py_ssize_t len;
-    int res;
-    PyObject *dict, *mydict;
     CDataObject *self = _CDataObject_CAST(myself);
-    if (!PyArg_ParseTuple(args, "O!s#",
-                          &PyDict_Type, &dict, &data, &len))
-    {
-        return NULL;
+
+    if (data_length > self->b_size) {
+        data_length = self->b_size;
     }
-    if (len > self->b_size)
-        len = self->b_size;
-    // XXX Can we use locked_memcpy_to()?
-    LOCK_PTR(self);
-    memmove(self->b_ptr, data, len);
-    UNLOCK_PTR(self);
-    mydict = PyObject_GetAttrString(myself, "__dict__");
+    memmove(self->b_ptr, data, data_length);
+    PyObject *mydict = PyObject_GetAttrString(myself, "__dict__");
     if (mydict == NULL) {
         return NULL;
     }
@@ -3074,26 +3075,30 @@ PyCData_setstate(PyObject *myself, PyObject *args)
         Py_DECREF(mydict);
         return NULL;
     }
-    res = PyDict_Update(mydict, dict);
+    int res = PyDict_Update(mydict, dict);
     Py_DECREF(mydict);
     if (res == -1)
         return NULL;
     Py_RETURN_NONE;
 }
 
-/*
- * default __ctypes_from_outparam__ method returns self.
- */
+/*[clinic input]
+_ctypes.PyCData.__ctypes_from_outparam__
+
+default __ctypes_from_outparam__ method returns self.
+[clinic start generated code]*/
+
 static PyObject *
-PyCData_from_outparam(PyObject *self, PyObject *args)
+_ctypes_PyCData___ctypes_from_outparam___impl(PyObject *self)
+/*[clinic end generated code: output=a7facc849097b549 input=910c5fec33e268c9]*/
 {
     return Py_NewRef(self);
 }
 
 static PyMethodDef PyCData_methods[] = {
-    { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
-    PYCDATA_REDUCE_METHODDEF
-    { "__setstate__", PyCData_setstate, METH_VARARGS, },
+    _CTYPES_PYCDATA___CTYPES_FROM_OUTPARAM___METHODDEF
+    _CTYPES_PYCDATA___SETSTATE___METHODDEF
+    _CTYPES_PYCDATA___REDUCE___METHODDEF
     { NULL, NULL },
 };
 
index 1f2e871137ed795846f61ad726004880d4534828..2b36f3592cc51ca85e5c7ea4444a691fef331bf2 100644 (file)
@@ -581,25 +581,82 @@ exit:
     return return_value;
 }
 
-PyDoc_STRVAR(PyCData_reduce__doc__,
+PyDoc_STRVAR(_ctypes_PyCData___reduce____doc__,
 "__reduce__($self, /)\n"
 "--\n"
 "\n");
 
-#define PYCDATA_REDUCE_METHODDEF    \
-    {"__reduce__", _PyCFunction_CAST(PyCData_reduce), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, PyCData_reduce__doc__},
+#define _CTYPES_PYCDATA___REDUCE___METHODDEF    \
+    {"__reduce__", _PyCFunction_CAST(_ctypes_PyCData___reduce__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _ctypes_PyCData___reduce____doc__},
 
 static PyObject *
-PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls);
+_ctypes_PyCData___reduce___impl(PyObject *myself, PyTypeObject *cls);
 
 static PyObject *
-PyCData_reduce(PyObject *myself, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_ctypes_PyCData___reduce__(PyObject *myself, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
+    PyObject *return_value = NULL;
+
     if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
         PyErr_SetString(PyExc_TypeError, "__reduce__() takes no arguments");
-        return NULL;
+        goto exit;
     }
-    return PyCData_reduce_impl(myself, cls);
+    Py_BEGIN_CRITICAL_SECTION(myself);
+    return_value = _ctypes_PyCData___reduce___impl(myself, cls);
+    Py_END_CRITICAL_SECTION();
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_ctypes_PyCData___setstate____doc__,
+"__setstate__($self, dict, data, /)\n"
+"--\n"
+"\n");
+
+#define _CTYPES_PYCDATA___SETSTATE___METHODDEF    \
+    {"__setstate__", _PyCFunction_CAST(_ctypes_PyCData___setstate__), METH_FASTCALL, _ctypes_PyCData___setstate____doc__},
+
+static PyObject *
+_ctypes_PyCData___setstate___impl(PyObject *myself, PyObject *dict,
+                                  const char *data, Py_ssize_t data_length);
+
+static PyObject *
+_ctypes_PyCData___setstate__(PyObject *myself, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *dict;
+    const char *data;
+    Py_ssize_t data_length;
+
+    if (!_PyArg_ParseStack(args, nargs, "O!s#:__setstate__",
+        &PyDict_Type, &dict, &data, &data_length)) {
+        goto exit;
+    }
+    Py_BEGIN_CRITICAL_SECTION(myself);
+    return_value = _ctypes_PyCData___setstate___impl(myself, dict, data, data_length);
+    Py_END_CRITICAL_SECTION();
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_ctypes_PyCData___ctypes_from_outparam____doc__,
+"__ctypes_from_outparam__($self, /)\n"
+"--\n"
+"\n"
+"default __ctypes_from_outparam__ method returns self.");
+
+#define _CTYPES_PYCDATA___CTYPES_FROM_OUTPARAM___METHODDEF    \
+    {"__ctypes_from_outparam__", (PyCFunction)_ctypes_PyCData___ctypes_from_outparam__, METH_NOARGS, _ctypes_PyCData___ctypes_from_outparam____doc__},
+
+static PyObject *
+_ctypes_PyCData___ctypes_from_outparam___impl(PyObject *self);
+
+static PyObject *
+_ctypes_PyCData___ctypes_from_outparam__(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _ctypes_PyCData___ctypes_from_outparam___impl(self);
 }
 
 #if !defined(_ctypes_CFuncPtr_errcheck_DOCSTR)
@@ -793,4 +850,4 @@ Simple_from_outparm(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py
     }
     return Simple_from_outparm_impl(self, cls);
 }
-/*[clinic end generated code: output=a18d87239b6fb8ca input=a9049054013a1b77]*/
+/*[clinic end generated code: output=2a1d935e9d8ceadd input=a9049054013a1b77]*/