[Python-checkins] cpython (3.1): check possible recursive _as_parameter_ to prevent segfault (closes #1838)

benjamin.peterson python-checkins at python.org
Sun Mar 27 00:16:48 CET 2011


http://hg.python.org/cpython/rev/4945a45b8be4
changeset:   68990:4945a45b8be4
branch:      3.1
parent:      68980:bd46aef7cf10
user:        Benjamin Peterson <benjamin at python.org>
date:        Sat Mar 26 17:56:28 2011 -0500
summary:
  check possible recursive _as_parameter_ to prevent segfault (closes #1838)

files:
  Lib/ctypes/test/test_as_parameter.py |  12 +++++++++++
  Lib/lib2to3/refactor.py              |   2 +-
  Lib/lib2to3/tests/test_refactor.py   |  17 ++++++++++++++++
  Misc/NEWS                            |   3 ++
  Modules/_ctypes/_ctypes.c            |  11 +++++++++-
  5 files changed, 43 insertions(+), 2 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/Lib/lib2to3/refactor.py b/Lib/lib2to3/refactor.py
--- a/Lib/lib2to3/refactor.py
+++ b/Lib/lib2to3/refactor.py
@@ -500,7 +500,7 @@
                         node = new
 
     def processed_file(self, new_text, filename, old_text=None, write=False,
-                       encoding=None):
+                       encoding=None, newlines=None):
         """
         Called when a file has been refactored, and there are changes.
         """
diff --git a/Lib/lib2to3/tests/test_refactor.py b/Lib/lib2to3/tests/test_refactor.py
--- a/Lib/lib2to3/tests/test_refactor.py
+++ b/Lib/lib2to3/tests/test_refactor.py
@@ -231,6 +231,23 @@
                 os.path.join("a_dir", "stuff.py")]
         check(tree, tree)
 
+    def test_preserve_file_newlines(self):
+        rt = self.rt(fixers=_2TO3_FIXERS)
+        for nl in ("\r\n", "\n"):
+            data = "print y%s%syes%sok%s" % ((nl,) * 4)
+            handle, tmp = tempfile.mkstemp()
+            os.close(handle)
+            try:
+                with open(tmp, "w") as fp:
+                    fp.write(data)
+                rt.refactor_file(tmp)
+                with open(tmp, "r") as fp:
+                    contents = fp.read()
+            finally:
+                os.unlink(tmp)
+            for line in contents.splitlines(True):
+                self.assertTrue(line.endswith(nl))
+
     def test_file_encoding(self):
         fn = os.path.join(TEST_DATA_DIR, "different_encoding.py")
         self.check_file_refactoring(fn)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -238,6 +238,9 @@
 Extensions
 ----------
 
+- Issue #1838: Prevent segfault in ctypes, when _as_parameter_ on a class is set
+  to an instance of the class.
+
 - Issue #678250: Make mmap flush a noop on ACCESS_READ and ACCESS_COPY.
 
 Build
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -2004,10 +2004,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;
     }
@@ -2036,7 +2040,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;
     }

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list