]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Backport:
authorNeal Norwitz <nnorwitz@gmail.com>
Mon, 13 Jan 2003 20:17:22 +0000 (20:17 +0000)
committerNeal Norwitz <nnorwitz@gmail.com>
Mon, 13 Jan 2003 20:17:22 +0000 (20:17 +0000)
Fix SF bug #667147, Segmentation fault printing str subclass

Fix infinite recursion which occurred when printing an object
whose __str__() returned self.

Lib/test/test_descr.py
Misc/NEWS
Objects/object.c

index 565d6d9dbac249cfc724ad64bf0ee20dcc3e3bd9..f92bba29c3ed192898a1bc86cff0f0aab320dbe0 100644 (file)
@@ -1,6 +1,6 @@
 # Test enhancements related to descriptors and new-style classes
 
-from test_support import verify, vereq, verbose, TestFailed, TESTFN
+from test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout
 from copy import deepcopy
 import warnings
 
@@ -1605,6 +1605,29 @@ def specials():
     unsafecmp(1, 1L)
     unsafecmp(1L, 1)
 
+    class Letter(str):
+        def __new__(cls, letter):
+            if letter == 'EPS':
+                return str.__new__(cls)
+            return str.__new__(cls, letter)
+        def __str__(self):
+            if not self:
+                return 'EPS'
+            return self 
+
+    # sys.stdout needs to be the original to trigger the recursion bug
+    import sys
+    test_stdout = sys.stdout
+    sys.stdout = get_original_stdout()
+    try:
+        # nothing should actually be printed, this should raise an exception
+        print Letter('w')
+    except RuntimeError:
+        pass
+    else:
+        raise TestFailed, "expected a RuntimeError for print recursion"
+    sys.stdout = test_stdout
+
 def weakrefs():
     if verbose: print "Testing weak references..."
     import weakref
index 022f53984d350b4b1b03a34d28a1bb08d48cf0c4..091501c9ed6557c5ee5ac900587d1aa6a271c3c0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -60,6 +60,8 @@ Release date: XX-XXX-2003
 
 - SF #659228, fix realpath() not being exported from os.path
 
+- SF #667147, fix crash when printing str subclass.
+
 What's New in Python 2.2.2 (final) ?
 Release date: 14-Oct-2002
 ====================================
index d68356f9e7ad6499e339d942cdb58ee0fb8b80f3..893be733cac7eea025d0ca026c6f55272df7b9f1 100644 (file)
@@ -146,10 +146,15 @@ _PyObject_Del(PyObject *op)
        PyObject_FREE(op);
 }
 
-int
-PyObject_Print(PyObject *op, FILE *fp, int flags)
+/* Implementation of PyObject_Print with recursion checking */
+static int
+internal_print(PyObject *op, FILE *fp, int flags, int nesting)
 {
        int ret = 0;
+       if (nesting > 10) {
+               PyErr_SetString(PyExc_RuntimeError, "print recursion");
+               return -1;
+       }
        if (PyErr_CheckSignals())
                return -1;
 #ifdef USE_STACKCHECK
@@ -175,7 +180,8 @@ PyObject_Print(PyObject *op, FILE *fp, int flags)
                        if (s == NULL)
                                ret = -1;
                        else {
-                               ret = PyObject_Print(s, fp, Py_PRINT_RAW);
+                               ret = internal_print(s, fp, Py_PRINT_RAW,
+                                                    nesting+1);
                        }
                        Py_XDECREF(s);
                }
@@ -192,6 +198,13 @@ PyObject_Print(PyObject *op, FILE *fp, int flags)
        return ret;
 }
 
+int
+PyObject_Print(PyObject *op, FILE *fp, int flags)
+{
+       return internal_print(op, fp, flags, 0);
+}
+
+
 /* For debugging convenience.  See Misc/gdbinit for some useful gdb hooks */
 void _PyObject_Dump(PyObject* op) 
 {