cpython: eed36e19f8b8 (original) (raw)
Mercurial > cpython
changeset 99356:eed36e19f8b8 3.4
Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside __getattr__. Original patch by Antoine Pitrou. [#24097]
Serhiy Storchaka storchaka@gmail.com | |
---|---|
date | Wed, 25 Nov 2015 18:33:29 +0200 |
parents | 8d9a0540adf9 |
children | 99839a1c9c6d e5eac1d692ad |
files | Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c |
diffstat | 3 files changed, 23 insertions(+), 0 deletions(-)[+] [-] Lib/test/test_descr.py 17 Misc/NEWS 3 Objects/typeobject.c 3 |
line wrap: on
line diff
--- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4988,6 +4988,23 @@ class PicklingTests(unittest.TestCase): objcopy2 = deepcopy(objcopy) self._assert_is_copy(obj, objcopy2)
- def test_issue24097(self):
# Slot name is freed inside __getattr__ and is later used.[](#l1.8)
class S(str): # Not interned[](#l1.9)
pass[](#l1.10)
class A:[](#l1.11)
__slotnames__ = [S('spam')][](#l1.12)
def __getattr__(self, attr):[](#l1.13)
if attr == 'spam':[](#l1.14)
A.__slotnames__[:] = [S('spam')][](#l1.15)
return 42[](#l1.16)
else:[](#l1.17)
raise AttributeError[](#l1.18)
import copyreg[](#l1.20)
expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None)[](#l1.21)
self.assertEqual(A().__reduce__(2), expected) # Shouldn't crash[](#l1.22)
+ class SharedKeyTests(unittest.TestCase):
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: tba Core and Builtins ----------------- +- Issue #24097: Fixed crash in object.reduce() if slot name is freed inside
- Issue #24731: Fixed crash on converting objects with special methods bytes, trunc, and float returning instances of subclasses of bytes, int, and float to subclasses of bytes, int, and float correspondingly.
--- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3768,8 +3768,10 @@ Py_LOCAL(PyObject *) PyObject *name, *value; name = PyList_GET_ITEM(slotnames, i);
Py_INCREF(name);[](#l3.7) value = PyObject_GetAttr(obj, name);[](#l3.8) if (value == NULL) {[](#l3.9)
Py_DECREF(name);[](#l3.10) if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {[](#l3.11) goto error;[](#l3.12) }[](#l3.13)
@@ -3778,6 +3780,7 @@ Py_LOCAL(PyObject *) } else { int err = PyDict_SetItem(slots, name, value);
Py_DECREF(name);[](#l3.18) Py_DECREF(value);[](#l3.19) if (err) {[](#l3.20) goto error;[](#l3.21)