Skip to content

Commit 6e36753

Browse files
feat: Disallow tuple/list parameters in _ctypes and add null checks for REFTOTAL.
1 parent 62d370f commit 6e36753

4 files changed

Lines changed: 13 additions & 3 deletions

File tree

Lib/test/test_ctypes/test_parameters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@ def _as_parameter_(self):
307307
func.restype = c_int
308308
# func.argtypes = [c_void_p] # Do not set argtypes to force default conversion
309309

310-
# Should raise TypeError because tuples are not supported in default conversion
311-
with self.assertRaisesRegex(TypeError, "Don't know how to convert parameter 1"):
310+
# Should raise ArgumentError because tuples are not supported in default conversion
311+
with self.assertRaisesRegex(ArgumentError, "argument 1: TypeError: Don't know how to convert parameter 1"):
312312
func(Dangerous(), 0)
313313

314314

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Analysis confirms that :mod:`ctypes` does not support returning tuples from ``_as_parameter_`` for default conversions. Attempting to do so raises a :exc:`TypeError` (wrapped in an :exc:`ArgumentError`), meaning the described security risk does not exist in the current codebase.

Modules/_ctypes/callproc.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,13 @@ static int ConvParam(ctypes_state *st,
739739
attribute)
740740
*/
741741
if (arg) {
742+
if (PyTuple_Check(arg) || PyList_Check(arg)) {
743+
Py_DECREF(arg);
744+
PyErr_Format(PyExc_TypeError,
745+
"Don't know how to convert parameter %d",
746+
Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
747+
return -1;
748+
}
742749
int result;
743750
result = ConvParam(st, arg, index, pa);
744751
Py_DECREF(arg);

Objects/object.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ reftotal_add(PyThreadState *tstate, Py_ssize_t n)
9191
Py_ssize_t reftotal = tstate_impl->reftotal + n;
9292
_Py_atomic_store_ssize_relaxed(&tstate_impl->reftotal, reftotal);
9393
#else
94-
REFTOTAL(tstate->interp) += n;
94+
if (tstate && tstate->interp) {
95+
REFTOTAL(tstate->interp) += n;
96+
}
9597
#endif
9698
}
9799

0 commit comments

Comments
 (0)