Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eb2389b

Browse files
committed
merge 3.2
2 parents b04d70d + 1a07f07 commit eb2389b

3 files changed

Lines changed: 72 additions & 20 deletions

File tree

Lib/ctypes/test/test_as_parameter.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,18 @@ class S8I(Structure):
187187
self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
188188
(9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
189189

190+
def test_recursive_as_param(self):
191+
from ctypes import c_int
192+
193+
class A(object):
194+
pass
195+
196+
a = A()
197+
a._as_parameter_ = a
198+
with self.assertRaises(RuntimeError):
199+
c_int.from_param(a)
200+
201+
190202
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191203

192204
class AsParamWrapper(object):

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,12 @@ Tools/Demos
322322

323323
- Issue #11179: Make ccbench work under Python 3.1 and 2.7 again.
324324

325+
Extensions
326+
----------
327+
328+
- Issue #1838: Prevent segfault in ctypes, when _as_parameter_ on a class is set
329+
to an instance of the class.
330+
325331
Tests
326332
-----
327333

Modules/_ctypes/_ctypes.c

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,10 @@ static PyObject *
585585
CDataType_from_param(PyObject *type, PyObject *value)
586586
{
587587
PyObject *as_parameter;
588-
if (1 == PyObject_IsInstance(value, type)) {
588+
int res = PyObject_IsInstance(value, type);
589+
if (res == -1)
590+
return NULL;
591+
if (res) {
589592
Py_INCREF(value);
590593
return value;
591594
}
@@ -598,10 +601,14 @@ CDataType_from_param(PyObject *type, PyObject *value)
598601

599602
/* If we got a PyCArgObject, we must check if the object packed in it
600603
is an instance of the type's dict->proto */
601-
if(dict && ob
602-
&& PyObject_IsInstance(ob, dict->proto)) {
603-
Py_INCREF(value);
604-
return value;
604+
if(dict && ob) {
605+
res = PyObject_IsInstance(ob, dict->proto);
606+
if (res == -1)
607+
return NULL;
608+
if (res) {
609+
Py_INCREF(value);
610+
return value;
611+
}
605612
}
606613
ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
607614
PyErr_Format(PyExc_TypeError,
@@ -951,8 +958,7 @@ PyCPointerType_from_param(PyObject *type, PyObject *value)
951958
Py_INCREF(value); /* _byref steals a refcount */
952959
return _byref(value);
953960
case -1:
954-
PyErr_Clear();
955-
break;
961+
return NULL;
956962
default:
957963
break;
958964
}
@@ -1431,6 +1437,7 @@ static PyObject *
14311437
c_wchar_p_from_param(PyObject *type, PyObject *value)
14321438
{
14331439
PyObject *as_parameter;
1440+
int res;
14341441
if (value == Py_None) {
14351442
Py_INCREF(Py_None);
14361443
return Py_None;
@@ -1451,7 +1458,10 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
14511458
}
14521459
return (PyObject *)parg;
14531460
}
1454-
if (PyObject_IsInstance(value, type)) {
1461+
res = PyObject_IsInstance(value, type);
1462+
if (res == -1)
1463+
return NULL;
1464+
if (res) {
14551465
Py_INCREF(value);
14561466
return value;
14571467
}
@@ -1492,6 +1502,7 @@ static PyObject *
14921502
c_char_p_from_param(PyObject *type, PyObject *value)
14931503
{
14941504
PyObject *as_parameter;
1505+
int res;
14951506
if (value == Py_None) {
14961507
Py_INCREF(Py_None);
14971508
return Py_None;
@@ -1512,7 +1523,10 @@ c_char_p_from_param(PyObject *type, PyObject *value)
15121523
}
15131524
return (PyObject *)parg;
15141525
}
1515-
if (PyObject_IsInstance(value, type)) {
1526+
res = PyObject_IsInstance(value, type);
1527+
if (res == -1)
1528+
return NULL;
1529+
if (res) {
15161530
Py_INCREF(value);
15171531
return value;
15181532
}
@@ -1554,6 +1568,7 @@ c_void_p_from_param(PyObject *type, PyObject *value)
15541568
{
15551569
StgDictObject *stgd;
15561570
PyObject *as_parameter;
1571+
int res;
15571572

15581573
/* None */
15591574
if (value == Py_None) {
@@ -1631,7 +1646,10 @@ c_void_p_from_param(PyObject *type, PyObject *value)
16311646
return (PyObject *)parg;
16321647
}
16331648
/* c_void_p instance (or subclass) */
1634-
if (PyObject_IsInstance(value, type)) {
1649+
res = PyObject_IsInstance(value, type);
1650+
if (res == -1)
1651+
return NULL;
1652+
if (res) {
16351653
/* c_void_p instances */
16361654
Py_INCREF(value);
16371655
return value;
@@ -1990,10 +2008,14 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
19902008
PyCArgObject *parg;
19912009
struct fielddesc *fd;
19922010
PyObject *as_parameter;
2011+
int res;
19932012

19942013
/* If the value is already an instance of the requested type,
19952014
we can use it as is */
1996-
if (1 == PyObject_IsInstance(value, type)) {
2015+
res = PyObject_IsInstance(value, type);
2016+
if (res == -1)
2017+
return NULL;
2018+
if (res) {
19972019
Py_INCREF(value);
19982020
return value;
19992021
}
@@ -2022,7 +2044,12 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
20222044

20232045
as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
20242046
if (as_parameter) {
2047+
if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
2048+
Py_DECREF(as_parameter);
2049+
return NULL;
2050+
}
20252051
value = PyCSimpleType_from_param(type, as_parameter);
2052+
Py_LeaveRecursiveCall();
20262053
Py_DECREF(as_parameter);
20272054
return value;
20282055
}
@@ -2714,6 +2741,7 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
27142741
Py_ssize_t size, char *ptr)
27152742
{
27162743
CDataObject *src;
2744+
int err;
27172745

27182746
if (setfunc)
27192747
return setfunc(ptr, value, size);
@@ -2754,7 +2782,10 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
27542782
}
27552783
src = (CDataObject *)value;
27562784

2757-
if (PyObject_IsInstance(value, type)) {
2785+
err = PyObject_IsInstance(value, type);
2786+
if (err == -1)
2787+
return NULL;
2788+
if (err) {
27582789
memcpy(ptr,
27592790
src->b_ptr,
27602791
size);
@@ -4749,14 +4780,17 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
47494780
stgdict = PyObject_stgdict((PyObject *)self);
47504781
assert(stgdict); /* Cannot be NULL fr pointer instances */
47514782
assert(stgdict->proto);
4752-
if (!CDataObject_Check(value)
4753-
|| 0 == PyObject_IsInstance(value, stgdict->proto)) {
4754-
/* XXX PyObject_IsInstance could return -1! */
4755-
PyErr_Format(PyExc_TypeError,
4756-
"expected %s instead of %s",
4757-
((PyTypeObject *)(stgdict->proto))->tp_name,
4758-
Py_TYPE(value)->tp_name);
4759-
return -1;
4783+
if (!CDataObject_Check(value)) {
4784+
int res = PyObject_IsInstance(value, stgdict->proto);
4785+
if (res == -1)
4786+
return -1;
4787+
if (!res) {
4788+
PyErr_Format(PyExc_TypeError,
4789+
"expected %s instead of %s",
4790+
((PyTypeObject *)(stgdict->proto))->tp_name,
4791+
Py_TYPE(value)->tp_name);
4792+
return -1;
4793+
}
47604794
}
47614795

47624796
dst = (CDataObject *)value;

0 commit comments

Comments
 (0)