mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									ad9604003c
								
							
						
					
					
						commit
						06847b13ca
					
				
					 2 changed files with 17 additions and 1 deletions
				
			
		| 
						 | 
					@ -1113,6 +1113,20 @@ def __format__(self, format_spec):
 | 
				
			||||||
        #  will fail
 | 
					        #  will fail
 | 
				
			||||||
        self.assertRaises(UnicodeEncodeError, "foo{0}".format, u'\u1000bar')
 | 
					        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():
 | 
					def test_main():
 | 
				
			||||||
    test_support.run_unittest(__name__)
 | 
					    test_support.run_unittest(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -315,7 +315,7 @@ PyUnicodeObject *_PyUnicode_New(Py_ssize_t length)
 | 
				
			||||||
	    if ((unicode->length < length) &&
 | 
						    if ((unicode->length < length) &&
 | 
				
			||||||
                unicode_resize(unicode, length) < 0) {
 | 
					                unicode_resize(unicode, length) < 0) {
 | 
				
			||||||
		PyObject_DEL(unicode->str);
 | 
							PyObject_DEL(unicode->str);
 | 
				
			||||||
		goto onError;
 | 
							unicode->str = NULL;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
| 
						 | 
					@ -352,6 +352,8 @@ PyUnicodeObject *_PyUnicode_New(Py_ssize_t length)
 | 
				
			||||||
    return unicode;
 | 
					    return unicode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 onError:
 | 
					 onError:
 | 
				
			||||||
 | 
					    /* XXX UNREF/NEWREF interface should be more symmetrical */
 | 
				
			||||||
 | 
					    _Py_DEC_REFTOTAL;
 | 
				
			||||||
    _Py_ForgetReference((PyObject *)unicode);
 | 
					    _Py_ForgetReference((PyObject *)unicode);
 | 
				
			||||||
    PyObject_Del(unicode);
 | 
					    PyObject_Del(unicode);
 | 
				
			||||||
    return NULL;
 | 
					    return NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue