From 06847b13ca28ef88e0ded4ce985c46317ba8cdaf Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Thu, 31 Jul 2008 23:39:05 +0000 Subject: Correct a crash when two successive unicode allocations fail with a MemoryError: the freelist contained half-initialized objects with freed pointers. The comment /* XXX UNREF/NEWREF interface should be more symmetrical */ was copied from tupleobject.c, and appears in some other places. I sign the petition. --- Lib/test/test_unicode.py | 14 ++++++++++++++ Objects/unicodeobject.c | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index f825353..b3d6907 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -1113,6 +1113,20 @@ class UnicodeTest( # will fail self.assertRaises(UnicodeEncodeError, "foo{0}".format, u'\u1000bar') + def test_raiseMemError(self): + # Ensure that the freelist contains a consistent object, even + # when a string allocation fails with a MemoryError. + # This used to crash the interpreter, + # or leak references when the number was smaller. + try: + u"a" * (sys.maxint // 2 - 100) + except MemoryError: + pass + try: + u"a" * (sys.maxint // 2 - 100) + except MemoryError: + pass + def test_main(): test_support.run_unittest(__name__) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7abf984..603c507 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -315,7 +315,7 @@ PyUnicodeObject *_PyUnicode_New(Py_ssize_t length) if ((unicode->length < length) && unicode_resize(unicode, length) < 0) { PyObject_DEL(unicode->str); - goto onError; + unicode->str = NULL; } } else { @@ -352,6 +352,8 @@ PyUnicodeObject *_PyUnicode_New(Py_ssize_t length) return unicode; onError: + /* XXX UNREF/NEWREF interface should be more symmetrical */ + _Py_DEC_REFTOTAL; _Py_ForgetReference((PyObject *)unicode); PyObject_Del(unicode); return NULL; -- cgit v0.12