diff options
author | Fredrik Lundh <fredrik@pythonware.com> | 2006-05-25 16:46:54 (GMT) |
---|---|---|
committer | Fredrik Lundh <fredrik@pythonware.com> | 2006-05-25 16:46:54 (GMT) |
commit | 0c71f88fc9da05517dae2d4c85a7dc059b3f1b4b (patch) | |
tree | 9dacc6c9532bf207ca554acfbcb086e51c658a4a /Objects/stringobject.c | |
parent | 44aa9f7139bb6e05756ca156a00ca2952761fe7e (diff) | |
download | cpython-0c71f88fc9da05517dae2d4c85a7dc059b3f1b4b.zip cpython-0c71f88fc9da05517dae2d4c85a7dc059b3f1b4b.tar.gz cpython-0c71f88fc9da05517dae2d4c85a7dc059b3f1b4b.tar.bz2 |
needforspeed: check for overflow in replace (from Andrew Dalke)
Diffstat (limited to 'Objects/stringobject.c')
-rw-r--r-- | Objects/stringobject.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 7bddeaa..77796df 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -2460,6 +2460,7 @@ mymemreplace(const char *str, Py_ssize_t len, /* input string */ char *out_s; char *new_s; Py_ssize_t nfound, offset, new_len; + Py_ssize_t product, delta; if (len == 0 || (pat_len == 0 && sub_len == 0) || pat_len > len) goto return_same; @@ -2473,7 +2474,24 @@ mymemreplace(const char *str, Py_ssize_t len, /* input string */ if (nfound == 0) goto return_same; - new_len = len + nfound*(sub_len - pat_len); + delta = (sub_len - pat_len); + if (delta == 0) { + new_len = len; + } else { + product = nfound * (sub_len - pat_len); + if ((product / (sub_len - pat_len)) != nfound) { + PyErr_SetString(PyExc_OverflowError, + "replace string is too long"); + return NULL; + } + new_len = len + product; + if (new_len < 0) { + PyErr_SetString(PyExc_OverflowError, + "replace string is too long"); + return NULL; + } + } + if (new_len == 0) { /* Have to allocate something for the caller to free(). */ out_s = (char *)PyMem_MALLOC(1); @@ -2578,7 +2596,8 @@ string_replace(PyStringObject *self, PyObject *args) new_s = mymemreplace(str,len,sub,sub_len,repl,repl_len,count,&out_len); if (new_s == NULL) { - PyErr_NoMemory(); + if (!PyErr_Occurred()) + PyErr_NoMemory(); return NULL; } if (out_len == -1) { |