http://hg.python.org/cpython/rev/4bd06503eaca changeset: 68992:4bd06503eaca branch: 2.7 parent: 68989:203e02427713 user: Benjamin Peterson <benjamin@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 @@ -245,6 +245,9 @@ Extension Modules ----------------- +- 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 @@ -2065,10 +2065,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; } @@ -2097,7 +2101,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