summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-07-31 23:39:05 +0000
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-07-31 23:39:05 +0000
commit06847b13ca28ef88e0ded4ce985c46317ba8cdaf (patch)
tree538beea91ca49f9cfeb724c4de85824cb45a2f4d
parentad9604003ccfcf956375bbc2aeaac078b7bc9b23 (diff)
downloadcpython-git-06847b13ca28ef88e0ded4ce985c46317ba8cdaf.tar.gz
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.
-rw-r--r--Lib/test/test_unicode.py14
-rw-r--r--Objects/unicodeobject.c4
2 files changed, 17 insertions, 1 deletions
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index f825353173..b3d6907eac 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 7abf984e66..603c5070a8 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;