From 1cb2e04238fa09094ce02d26833a19d2bd70d81d Mon Sep 17 00:00:00 2001 From: Armin Rigo Date: Sun, 4 Mar 2012 18:56:23 +0100 Subject: [PATCH] Add a crasher for the documented issue of calling "Py_DECREF(self->xxx)"; --- Lib/test/crashers/decref_before_assignment.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Lib/test/crashers/decref_before_assignment.py diff --git a/Lib/test/crashers/decref_before_assignment.py b/Lib/test/crashers/decref_before_assignment.py new file mode 100644 index 00000000000..b5b17fa1498 --- /dev/null +++ b/Lib/test/crashers/decref_before_assignment.py @@ -0,0 +1,44 @@ +""" +General example for an attack against code like this: + + Py_DECREF(obj->attr); obj->attr = ...; + +here in Module/_json.c:scanner_init(). + +Explanation: if the first Py_DECREF() calls either a __del__ or a +weakref callback, it will run while the 'obj' appears to have in +'obj->attr' still the old reference to the object, but not holding +the reference count any more. + +Status: progress has been made replacing these cases, but there is an +infinite number of such cases. +""" + +import _json, weakref + +class Ctx1(object): + encoding = "utf8" + strict = None + object_hook = None + object_pairs_hook = None + parse_float = None + parse_int = None + parse_constant = None + +class Foo(unicode): + pass + +def delete_me(*args): + print scanner.encoding.__dict__ + +class Ctx2(Ctx1): + @property + def encoding(self): + global wref + f = Foo("utf8") + f.abc = globals() + wref = weakref.ref(f, delete_me) + return f + +scanner = _json.make_scanner(Ctx1()) +scanner.__init__(Ctx2())