From 7888d0803d50fc3716839d0608bdf350cc0e3df4 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Fri, 1 Aug 2008 01:06:32 +0000 Subject: [PATCH] Merged revisions 65339-65340,65342 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ r65339 | amaury.forgeotdarc | 2008-07-31 23:28:03 +0200 (jeu., 31 juil. 2008) | 5 lines #3479: unichr(2**32) used to return u'\x00'. The argument was fetched in a long, but PyUnicode_FromOrdinal takes an int. (why doesn't gcc issue a truncation warning in this case?) ........ r65340 | amaury.forgeotdarc | 2008-07-31 23:35:03 +0200 (jeu., 31 juil. 2008) | 2 lines Remove a dummy test that was checked in by mistake ........ r65342 | amaury.forgeotdarc | 2008-08-01 01:39:05 +0200 (ven., 01 août 2008) | 8 lines 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_builtin.py | 1 + Lib/test/test_exceptions.py | 8 -------- Lib/test/test_unicode.py | 14 ++++++++++++++ Objects/unicodeobject.c | 4 +++- Python/bltinmodule.c | 4 ++-- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 7a898b25de4..f8d4ae0e44d 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -216,6 +216,7 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(chr(0x0010FFFF), "\U0010FFFF") self.assertRaises(ValueError, chr, -1) self.assertRaises(ValueError, chr, 0x00110000) + self.assertRaises((OverflowError, ValueError), chr, 2**32) def test_cmp(self): self.assertEqual(cmp(-1, 1), -1) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index b742fcefd73..95c2dd143b3 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -12,14 +12,6 @@ from test.support import TESTFN, unlink, run_unittest, captured_output class ExceptionTests(unittest.TestCase): - def test00(self): - try: - sys.exit(ValueError('aaa')) - except SystemExit: - pass - finally: - pass - def raise_catch(self, exc, excname): try: raise exc("spam") diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 604fdf28ed4..fdd90ca1665 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -1156,6 +1156,20 @@ class UnicodeTest( self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxsize) + 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: + "a" * (sys.maxsize // 2 - 100) + except MemoryError: + pass + try: + "a" * (sys.maxsize // 2 - 100) + except MemoryError: + pass + def test_main(): support.run_unittest(__name__) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 838f537e02b..5925f8077f5 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -322,7 +322,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 { @@ -360,6 +360,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; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 723c307b8f0..27a3d8c005e 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -454,9 +454,9 @@ format_spec defaults to \"\""); static PyObject * builtin_chr(PyObject *self, PyObject *args) { - long x; + int x; - if (!PyArg_ParseTuple(args, "l:chr", &x)) + if (!PyArg_ParseTuple(args, "i:chr", &x)) return NULL; return PyUnicode_FromOrdinal(x);