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.
This commit is contained in:
Tim Peters 2002-04-27 18:44:32 +00:00
parent 602f740bc2
commit 5de9842b34
14 changed files with 54 additions and 90 deletions

View file

@ -1869,8 +1869,8 @@ string_translate(PyStringObject *self, PyObject *args)
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 @@ PyString_ConcatAndDel(register PyObject **pv, register PyObject *w)
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)