[Python-checkins] cpython (merge 3.2 -> default): merge 3.2
benjamin.peterson
python-checkins at python.org
Sun Mar 27 00:17:04 CET 2011
http://hg.python.org/cpython/rev/b44156fdc7f2
changeset: 68998:b44156fdc7f2
parent: 68988:8bdc20468cbc
parent: 68997:d5c819d597fe
user: Benjamin Peterson <benjamin at python.org>
date: Sat Mar 26 18:18:09 2011 -0500
summary:
merge 3.2
files:
Lib/ctypes/test/test_as_parameter.py | 12 ++
Misc/NEWS | 6 +
Modules/_ctypes/_ctypes.c | 74 +++++++++++----
3 files changed, 72 insertions(+), 20 deletions(-)
diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/ctypes/test/test_as_parameter.py
--- a/Lib/ctypes/test/test_as_parameter.py
+++ b/Lib/ctypes/test/test_as_parameter.py
@@ -187,6 +187,18 @@
self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
(9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
+ def test_recursive_as_param(self):
+ from ctypes import c_int
+
+ class A(object):
+ pass
+
+ a = A()
+ a._as_parameter_ = a
+ with self.assertRaises(RuntimeError):
+ c_int.from_param(a)
+
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class AsParamWrapper(object):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -322,6 +322,12 @@
- Issue #11179: Make ccbench work under Python 3.1 and 2.7 again.
+Extensions
+----------
+
+- Issue #1838: Prevent segfault in ctypes, when _as_parameter_ on a class is set
+ to an instance of the class.
+
Tests
-----
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -585,7 +585,10 @@
CDataType_from_param(PyObject *type, PyObject *value)
{
PyObject *as_parameter;
- if (1 == PyObject_IsInstance(value, type)) {
+ int res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
Py_INCREF(value);
return value;
}
@@ -598,10 +601,14 @@
/* If we got a PyCArgObject, we must check if the object packed in it
is an instance of the type's dict->proto */
- if(dict && ob
- && PyObject_IsInstance(ob, dict->proto)) {
- Py_INCREF(value);
- return value;
+ if(dict && ob) {
+ res = PyObject_IsInstance(ob, dict->proto);
+ if (res == -1)
+ return NULL;
+ if (res) {
+ Py_INCREF(value);
+ return value;
+ }
}
ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
PyErr_Format(PyExc_TypeError,
@@ -951,8 +958,7 @@
Py_INCREF(value); /* _byref steals a refcount */
return _byref(value);
case -1:
- PyErr_Clear();
- break;
+ return NULL;
default:
break;
}
@@ -1431,6 +1437,7 @@
c_wchar_p_from_param(PyObject *type, PyObject *value)
{
PyObject *as_parameter;
+ int res;
if (value == Py_None) {
Py_INCREF(Py_None);
return Py_None;
@@ -1451,7 +1458,10 @@
}
return (PyObject *)parg;
}
- if (PyObject_IsInstance(value, type)) {
+ res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
Py_INCREF(value);
return value;
}
@@ -1492,6 +1502,7 @@
c_char_p_from_param(PyObject *type, PyObject *value)
{
PyObject *as_parameter;
+ int res;
if (value == Py_None) {
Py_INCREF(Py_None);
return Py_None;
@@ -1512,7 +1523,10 @@
}
return (PyObject *)parg;
}
- if (PyObject_IsInstance(value, type)) {
+ res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
Py_INCREF(value);
return value;
}
@@ -1554,6 +1568,7 @@
{
StgDictObject *stgd;
PyObject *as_parameter;
+ int res;
/* None */
if (value == Py_None) {
@@ -1631,7 +1646,10 @@
return (PyObject *)parg;
}
/* c_void_p instance (or subclass) */
- if (PyObject_IsInstance(value, type)) {
+ res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
/* c_void_p instances */
Py_INCREF(value);
return value;
@@ -1990,10 +2008,14 @@
PyCArgObject *parg;
struct fielddesc *fd;
PyObject *as_parameter;
+ int res;
/* If the value is already an instance of the requested type,
we can use it as is */
- if (1 == PyObject_IsInstance(value, type)) {
+ res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
Py_INCREF(value);
return value;
}
@@ -2022,7 +2044,12 @@
as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
if (as_parameter) {
+ if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
+ Py_DECREF(as_parameter);
+ return NULL;
+ }
value = PyCSimpleType_from_param(type, as_parameter);
+ Py_LeaveRecursiveCall();
Py_DECREF(as_parameter);
return value;
}
@@ -2714,6 +2741,7 @@
Py_ssize_t size, char *ptr)
{
CDataObject *src;
+ int err;
if (setfunc)
return setfunc(ptr, value, size);
@@ -2754,7 +2782,10 @@
}
src = (CDataObject *)value;
- if (PyObject_IsInstance(value, type)) {
+ err = PyObject_IsInstance(value, type);
+ if (err == -1)
+ return NULL;
+ if (err) {
memcpy(ptr,
src->b_ptr,
size);
@@ -4749,14 +4780,17 @@
stgdict = PyObject_stgdict((PyObject *)self);
assert(stgdict); /* Cannot be NULL fr pointer instances */
assert(stgdict->proto);
- if (!CDataObject_Check(value)
- || 0 == PyObject_IsInstance(value, stgdict->proto)) {
- /* XXX PyObject_IsInstance could return -1! */
- PyErr_Format(PyExc_TypeError,
- "expected %s instead of %s",
- ((PyTypeObject *)(stgdict->proto))->tp_name,
- Py_TYPE(value)->tp_name);
- return -1;
+ if (!CDataObject_Check(value)) {
+ int res = PyObject_IsInstance(value, stgdict->proto);
+ if (res == -1)
+ return -1;
+ if (!res) {
+ PyErr_Format(PyExc_TypeError,
+ "expected %s instead of %s",
+ ((PyTypeObject *)(stgdict->proto))->tp_name,
+ Py_TYPE(value)->tp_name);
+ return -1;
+ }
}
dst = (CDataObject *)value;
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list