Commit dc303547 authored by Guido van Rossum's avatar Guido van Rossum

Fix test67.py from issue #1303614.

parent a654b464
# http://python.org/sf/1303614
class Strange(object):
def __hash__(self):
return hash('hello')
def __eq__(self, other):
x.__dict__ = {} # the old x.__dict__ is deallocated
return False
class X(object):
pass
if __name__ == '__main__':
v = 123
x = X()
x.__dict__ = {Strange(): 42,
'hello': v+456}
x.hello # segfault: the above dict is accessed after it's deallocated
...@@ -4504,6 +4504,29 @@ def test_borrowed_ref_4_segfault(): ...@@ -4504,6 +4504,29 @@ def test_borrowed_ref_4_segfault():
finally: finally:
__builtin__.__import__ = orig_import __builtin__.__import__ = orig_import
def test_losing_dict_ref_segfault():
# This used to segfault;
# derived from issue #1303614, test67.py
if verbose:
print "Testing losing dict ref segfault..."
class Strange(object):
def __hash__(self):
return hash('hello')
def __eq__(self, other):
x.__dict__ = {} # the old x.__dict__ is deallocated
return False
class X(object):
pass
v = 123
x = X()
x.__dict__ = {Strange(): 42, 'hello': v+456}
x.hello
def test_main(): def test_main():
weakref_segfault() # Must be first, somehow weakref_segfault() # Must be first, somehow
wrapper_segfault() wrapper_segfault()
...@@ -4606,6 +4629,7 @@ def test_main(): ...@@ -4606,6 +4629,7 @@ def test_main():
test_weakref_in_del_segfault() test_weakref_in_del_segfault()
test_borrowed_ref_3_segfault() test_borrowed_ref_3_segfault()
test_borrowed_ref_4_segfault() test_borrowed_ref_4_segfault()
test_losing_dict_ref_segfault()
if verbose: print "All OK" if verbose: print "All OK"
......
...@@ -1349,12 +1349,15 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) ...@@ -1349,12 +1349,15 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
dictptr = (PyObject **) ((char *)obj + dictoffset); dictptr = (PyObject **) ((char *)obj + dictoffset);
dict = *dictptr; dict = *dictptr;
if (dict != NULL) { if (dict != NULL) {
Py_INCREF(dict);
res = PyDict_GetItem(dict, name); res = PyDict_GetItem(dict, name);
if (res != NULL) { if (res != NULL) {
Py_INCREF(res); Py_INCREF(res);
Py_XDECREF(descr); Py_XDECREF(descr);
Py_DECREF(dict);
goto done; goto done;
} }
Py_DECREF(dict);
} }
} }
...@@ -1435,12 +1438,14 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) ...@@ -1435,12 +1438,14 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
*dictptr = dict; *dictptr = dict;
} }
if (dict != NULL) { if (dict != NULL) {
Py_INCREF(dict);
if (value == NULL) if (value == NULL)
res = PyDict_DelItem(dict, name); res = PyDict_DelItem(dict, name);
else else
res = PyDict_SetItem(dict, name, value); res = PyDict_SetItem(dict, name, value);
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
PyErr_SetObject(PyExc_AttributeError, name); PyErr_SetObject(PyExc_AttributeError, name);
Py_DECREF(dict);
goto done; goto done;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment