From 6d8333020cf2e2f1e50245db907463f53efca528 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sat, 27 Apr 2002 18:44:32 +0000 Subject: 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. --- Objects/stringobject.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'Objects/stringobject.c') diff --git a/Objects/stringobject.c b/Objects/stringobject.c index d3c9e4bdf7..5bad04e552 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -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) -- cgit v1.2.1