[pypy-commit] pypy default: cpyext: Fix crash in PyDict_Next when the pointer for values is NULL.
amauryfa
noreply at buildbot.pypy.org
Sat Feb 18 15:57:50 CET 2012
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r52605:568fc4237bf8
Date: 2012-02-18 15:56 +0100
http://bitbucket.org/pypy/pypy/changeset/568fc4237bf8/
Log: cpyext: Fix crash in PyDict_Next when the pointer for values is
NULL.
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -184,8 +184,10 @@
w_item = space.call_method(w_iter, "next")
w_key, w_value = space.fixedview(w_item, 2)
state = space.fromcache(RefcountState)
- pkey[0] = state.make_borrowed(w_dict, w_key)
- pvalue[0] = state.make_borrowed(w_dict, w_value)
+ if pkey:
+ pkey[0] = state.make_borrowed(w_dict, w_key)
+ if pvalue:
+ pvalue[0] = state.make_borrowed(w_dict, w_value)
ppos[0] += 1
except OperationError, e:
if not e.match(space, space.w_StopIteration):
diff --git a/pypy/module/cpyext/test/test_dictobject.py b/pypy/module/cpyext/test/test_dictobject.py
--- a/pypy/module/cpyext/test/test_dictobject.py
+++ b/pypy/module/cpyext/test/test_dictobject.py
@@ -112,6 +112,37 @@
assert space.eq_w(space.len(w_copy), space.len(w_dict))
assert space.eq_w(w_copy, w_dict)
+ def test_iterkeys(self, space, api):
+ w_dict = space.sys.getdict(space)
+ py_dict = make_ref(space, w_dict)
+
+ ppos = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
+ pkey = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+ pvalue = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+
+ keys_w = []
+ values_w = []
+ try:
+ ppos[0] = 0
+ while api.PyDict_Next(w_dict, ppos, pkey, None):
+ w_key = from_ref(space, pkey[0])
+ keys_w.append(w_key)
+ ppos[0] = 0
+ while api.PyDict_Next(w_dict, ppos, None, pvalue):
+ w_value = from_ref(space, pvalue[0])
+ values_w.append(w_value)
+ finally:
+ lltype.free(ppos, flavor='raw')
+ lltype.free(pkey, flavor='raw')
+ lltype.free(pvalue, flavor='raw')
+
+ api.Py_DecRef(py_dict) # release borrowed references
+
+ assert space.eq_w(space.newlist(keys_w),
+ space.call_method(w_dict, "keys"))
+ assert space.eq_w(space.newlist(values_w),
+ space.call_method(w_dict, "values"))
+
def test_dictproxy(self, space, api):
w_dict = space.sys.get('modules')
w_proxy = api.PyDictProxy_New(w_dict)
More information about the pypy-commit
mailing list