Mercurial > cpython-lru_cache-weakref
diff Objects/unicodeobject.c @ 30766:982e3e40bf1e 2.3
Backport checkin:
Fix a bug in the memory reallocation code of PyUnicode_TranslateCharmap().
charmaptranslate_makespace() allocates more memory than required for the
next replacement but didn't remember that fact, so memory size was growing
exponentially every time a replacement string is longer that one character.
This fixes SF bug #828737.
| author | Walter Dörwald <walter@livinglogic.de> |
|---|---|
| date | Fri, 24 Oct 2003 15:05:29 +0000 |
| parents | be0ca26ad574 |
| children | 566737bfaec9 |
line wrap: on
line diff
--- a/Objects/unicodeobject.c Thu Oct 23 15:55:03 2003 +0000 +++ b/Objects/unicodeobject.c Fri Oct 24 15:05:29 2003 +0000 @@ -3223,19 +3223,19 @@ if not reallocate and adjust various state variables. Return 0 on success, -1 on error */ static -int charmaptranslate_makespace(PyObject **outobj, Py_UNICODE **outp, int *outsize, +int charmaptranslate_makespace(PyObject **outobj, Py_UNICODE **outp, int requiredsize) { - if (requiredsize > *outsize) { + int oldsize = PyUnicode_GET_SIZE(*outobj); + if (requiredsize > oldsize) { /* remember old output position */ int outpos = *outp-PyUnicode_AS_UNICODE(*outobj); /* exponentially overallocate to minimize reallocations */ - if (requiredsize < 2 * *outsize) - requiredsize = 2 * *outsize; + if (requiredsize < 2 * oldsize) + requiredsize = 2 * oldsize; if (_PyUnicode_Resize(outobj, requiredsize)) return -1; *outp = PyUnicode_AS_UNICODE(*outobj) + outpos; - *outsize = requiredsize; } return 0; } @@ -3246,14 +3246,15 @@ The called must decref result. Return 0 on success, -1 on error. */ static -int charmaptranslate_output(Py_UNICODE c, PyObject *mapping, - PyObject **outobj, int *outsize, Py_UNICODE **outp, PyObject **res) -{ - if (charmaptranslate_lookup(c, mapping, res)) +int charmaptranslate_output(const Py_UNICODE *startinp, const Py_UNICODE *curinp, + int insize, PyObject *mapping, PyObject **outobj, Py_UNICODE **outp, + PyObject **res) +{ + if (charmaptranslate_lookup(*curinp, mapping, res)) return -1; if (*res==NULL) { /* not found => default to 1:1 mapping */ - *(*outp)++ = (Py_UNICODE)c; + *(*outp)++ = *curinp; } else if (*res==Py_None) ; @@ -3269,8 +3270,10 @@ } else if (repsize!=0) { /* more than one character */ - int requiredsize = *outsize + repsize - 1; - if (charmaptranslate_makespace(outobj, outp, outsize, requiredsize)) + int requiredsize = (*outp-PyUnicode_AS_UNICODE(*outobj)) + + (insize - (*curinp-*startinp)) + + repsize - 1; + if (charmaptranslate_makespace(outobj, outp, requiredsize)) return -1; memcpy(*outp, PyUnicode_AS_UNICODE(*res), sizeof(Py_UNICODE)*repsize); *outp += repsize; @@ -3295,7 +3298,6 @@ Py_UNICODE *str; /* current output position */ int respos = 0; - int ressize; char *reason = "character maps to <undefined>"; PyObject *errorHandler = NULL; PyObject *exc = NULL; @@ -3313,16 +3315,15 @@ replacements, if we need more, we'll resize */ res = PyUnicode_FromUnicode(NULL, size); if (res == NULL) - goto onError; + goto onError; if (size == 0) return res; str = PyUnicode_AS_UNICODE(res); - ressize = size; while (p<endp) { /* try to encode it */ PyObject *x = NULL; - if (charmaptranslate_output(*p, mapping, &res, &ressize, &str, &x)) { + if (charmaptranslate_output(startp, p, size, mapping, &res, &str, &x)) { Py_XDECREF(x); goto onError; } @@ -3341,7 +3342,7 @@ /* find all untranslatable characters */ while (collend < endp) { - if (charmaptranslate_lookup(*collend, mapping, &x)) + if (charmaptranslate_lookup(*collend, mapping, &x)) goto onError; Py_XDECREF(x); if (x!=Py_None) @@ -3380,7 +3381,7 @@ char buffer[2+29+1+1]; char *cp; sprintf(buffer, "&#%d;", (int)*p); - if (charmaptranslate_makespace(&res, &str, &ressize, + if (charmaptranslate_makespace(&res, &str, (str-PyUnicode_AS_UNICODE(res))+strlen(buffer)+(endp-collend))) goto onError; for (cp = buffer; *cp; ++cp) @@ -3396,7 +3397,7 @@ goto onError; /* generate replacement */ repsize = PyUnicode_GET_SIZE(repunicode); - if (charmaptranslate_makespace(&res, &str, &ressize, + if (charmaptranslate_makespace(&res, &str, (str-PyUnicode_AS_UNICODE(res))+repsize+(endp-collend))) { Py_DECREF(repunicode); goto onError; @@ -3410,7 +3411,7 @@ } /* Resize if we allocated to much */ respos = str-PyUnicode_AS_UNICODE(res); - if (respos<ressize) { + if (respos<PyUnicode_GET_SIZE(res)) { if (_PyUnicode_Resize(&res, respos)) goto onError; }
