diff Objects/stringobject.c @ 23295:6fa76b4e59fe legacy-trunk

Repair widespread misuse of _PyString_Resize. Since it's clear people don't understand how this function works, also beefed up the docs. The most common usage error is of this form (often spread out across gotos): if (_PyString_Resize(&s, n) < 0) { Py_DECREF(s); s = NULL; goto outtahere; } The error is that if _PyString_Resize runs out of memory, it automatically decrefs the input string object s (which also deallocates it, since its refcount must be 1 upon entry), and sets s to NULL. So if the "if" branch ever triggers, it's an error to call Py_DECREF(s): s is already NULL! A correct way to write the above is the simpler (and intended) if (_PyString_Resize(&s, n) < 0) goto outtahere; Bugfix candidate.
author Tim Peters <tim.peters@gmail.com>
date Sat, 27 Apr 2002 18:44:32 +0000
parents e639e34ef901
children 1be6e79b1d46
line wrap: on
line diff
--- a/Objects/stringobject.c	Sat Apr 27 18:03:26 2002 +0000
+++ b/Objects/stringobject.c	Sat Apr 27 18:44:32 2002 +0000
@@ -1869,8 +1869,8 @@
 		return input_obj;
 	}
 	/* Fix the size of the resulting string */
-	if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
-		return NULL;
+	if (inlen > 0)
+		_PyString_Resize(&result, output - output_start);
 	return result;
 }
 
@@ -2927,7 +2927,14 @@
    is only one module referencing the object.  You can also think of it
    as creating a new string object and destroying the old one, only
    more efficiently.  In any case, don't use this if the string may
-   already be known to some other part of the code... */
+   already be known to some other part of the code...
+   Note that if there's not enough memory to resize the string, the original
+   string object at *pv is deallocated, *pv is set to NULL, an "out of
+   memory" exception is set, and -1 is returned.  Else (on success) 0 is
+   returned, and the value in *pv may or may not be the same as on input.
+   As always, an extra byte is allocated for a trailing \0 byte (newsize
+   does *not* include that), and a trailing \0 byte is stored.
+*/
 
 int
 _PyString_Resize(PyObject **pv, int newsize)