From: Stefan Behnel Date: Sun, 26 Dec 2010 21:34:22 +0000 (+0100) Subject: fix bug 633: make sure we own references to Python arguments passed into C functions X-Git-Tag: 0.14.1rc0~13^2~7 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=cd9d2b2a3611f23f4c044c3e2a1f852583e078f7;p=cython.git fix bug 633: make sure we own references to Python arguments passed into C functions --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index c0440641..8aead92c 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -2953,7 +2953,14 @@ class SimpleCallNode(CallNode): # Coerce arguments for i in range(min(max_nargs, actual_nargs)): formal_type = func_type.args[i].type - self.args[i] = self.args[i].coerce_to(formal_type, env) + arg = self.args[i].coerce_to(formal_type, env) + if arg.is_attribute or not arg.is_simple: + # we do not own the argument's reference, but we must + # make sure it cannot be collected before we return + # from the function, so we create an owned temp + # reference to it + arg = arg.coerce_to_temp(env) + self.args[i] = arg for i in range(max_nargs, actual_nargs): if self.args[i].type.is_pyobject: error(self.args[i].pos, diff --git a/tests/run/owned_arg_refs.pyx b/tests/run/owned_arg_refs.pyx new file mode 100644 index 00000000..5bf84d76 --- /dev/null +++ b/tests/run/owned_arg_refs.pyx @@ -0,0 +1,28 @@ + +cdef class Owner: + cdef object x + +cdef call_me_with_owner(Owner owner, x): + owner.x = "def" # overwrite external reference + return x # crashes if x is not owned by function or caller + +def test_ext_type_attr(): + """ + >>> test_ext_type_attr() + 'abc5' + """ + owner = Owner() + owner.x = ''.join("abc%d" % 5) # non-interned object + return call_me_with_owner(owner, owner.x) + +cdef call_me_with_list(list l, x): + l[:] = [(1,2), (3,4)] # overwrite external reference + return x # crashes if x is not owned by function or caller + +def test_index(): + """ + >>> test_index() + [3, 4] + """ + l = [[1,2],[3,4]] + return call_me_with_list(l, l[1])