]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
backport tim_one's patch:
authorAnthony Baxter <anthonybaxter@gmail.com>
Tue, 30 Apr 2002 03:58:47 +0000 (03:58 +0000)
committerAnthony Baxter <anthonybaxter@gmail.com>
Tue, 30 Apr 2002 03:58:47 +0000 (03:58 +0000)
[Re-did unicodeobject.c - it's changed a lot since 2.1 :) Pretty confident
that it's correct]

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.

Original patch(es):
python/dist/src/Objects/fileobject.c:2.161
python/dist/src/Objects/stringobject.c:2.161
python/dist/src/Objects/unicodeobject.c:2.147

Objects/fileobject.c
Objects/stringobject.c
Objects/unicodeobject.c

index 3f4eeb9f90c3392219b6287cd26db7009ef585fe..3b1106fc4867d0d07ed30fe9b76796366b1fcb60 100644 (file)
@@ -1104,9 +1104,7 @@ file_readlines(PyFileObject *f, PyObject *args)
                        goto error;
        }
   cleanup:
-       if (big_buffer) {
-               Py_DECREF(big_buffer);
-       }
+       Py_XDECREF(big_buffer);
        return list;
 }
 
index 25a7c92a9d2151b33aa0f7c2619fb75dd43b9efa..9cfbf28ad5a6843415bd1570b5f6e8af1c0c567f 100644 (file)
@@ -1449,8 +1449,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;
 }
 
@@ -2425,7 +2425,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)
index 76ca94c902ed50ab3070db76aa11f706aa74761f..15da47b26740fb78a555d336e7dea80edb24c378 100644 (file)
@@ -864,7 +864,6 @@ PyObject *PyUnicode_EncodeUTF8(const Py_UNICODE *s,
     return v;
 
  onError:
-    Py_DECREF(v);
     return NULL;
 }
 
@@ -1365,7 +1364,6 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
     return repr;
 
  onError:
-    Py_DECREF(repr);
     return NULL;
 }
 
@@ -1501,7 +1499,6 @@ PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s,
     return repr;
 
  onError:
-    Py_DECREF(repr);
     return NULL;
 }
 
@@ -1589,8 +1586,10 @@ PyObject *PyUnicode_EncodeLatin1(const Py_UNICODE *p,
         Py_UNICODE ch = *p++;
        if (ch >= 256) {
            if (latin1_encoding_error(&p, &s, errors, 
-                                     "ordinal not in range(256)"))
+                                     "ordinal not in range(256)")) {
+               Py_DECREF(repr);
                goto onError;
+           }
        }
        else
             *s++ = (char)ch;
@@ -1602,7 +1601,6 @@ PyObject *PyUnicode_EncodeLatin1(const Py_UNICODE *p,
     return repr;
 
  onError:
-    Py_DECREF(repr);
     return NULL;
 }
 
@@ -1732,8 +1730,10 @@ PyObject *PyUnicode_EncodeASCII(const Py_UNICODE *p,
         Py_UNICODE ch = *p++;
        if (ch >= 128) {
            if (ascii_encoding_error(&p, &s, errors, 
-                                     "ordinal not in range(128)"))
+                                     "ordinal not in range(128)")) {
+               Py_DECREF(repr);
                goto onError;
+           }
        }
        else
             *s++ = (char)ch;
@@ -1745,7 +1745,6 @@ PyObject *PyUnicode_EncodeASCII(const Py_UNICODE *p,
     return repr;
 
  onError:
-    Py_DECREF(repr);
     return NULL;
 }
 
@@ -2018,7 +2017,7 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
        /* Get mapping (Unicode ordinal -> string char, integer or None) */
        w = PyInt_FromLong((long)ch);
        if (w == NULL)
-           goto onError;
+           goto onErrorDecref;
        x = PyObject_GetItem(mapping, w);
        Py_DECREF(w);
        if (x == NULL) {
@@ -2028,7 +2027,7 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
                x = Py_None;
                Py_INCREF(x);
            } else
-               goto onError;
+               goto onErrorDecref;
        }
 
        /* Apply mapping */
@@ -2038,7 +2037,7 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
                PyErr_SetString(PyExc_TypeError,
                                "character mapping must be in range(256)");
                Py_DECREF(x);
-               goto onError;
+               goto onErrorDecref;
            }
            *s++ = (char)value;
        }
@@ -2047,7 +2046,7 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
            if (charmap_encoding_error(&p, &s, errors, 
                                       "character maps to <undefined>")) {
                Py_DECREF(x);
-               goto onError;
+               goto onErrorDecref;
            }
        }
        else if (PyString_Check(x)) {
@@ -2066,7 +2065,7 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
                                 (targetsize << 2);
                    extrachars += needed;
                    if (_PyString_Resize(&v, PyString_GET_SIZE(v) + needed)) {
-                       Py_DECREF(x);
+                       Py_DECREF(x); 
                        goto onError;
                    }
                    s = PyString_AS_STRING(v) + oldpos;
@@ -2084,7 +2083,7 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
            PyErr_SetString(PyExc_TypeError,
                  "character mapping must return integer, None or unicode");
            Py_DECREF(x);
-           goto onError;
+           goto onErrorDecref;
        }
        Py_DECREF(x);
     }
@@ -2093,8 +2092,9 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
            goto onError;
     return v;
 
- onError:
+ onErrorDecref:
     Py_DECREF(v);
+ onError:
     return NULL;
 }