gh-128182: add critical section to _ctypes.PyCData methods (#132082)

This commit is contained in:
Kumar Aditya 2025-04-05 15:24:58 +05:30 committed by GitHub
parent 37bc3865c8
commit f7a8bc50db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 99 additions and 37 deletions

View 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 },
};

View 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]*/