summaryrefslogtreecommitdiffstats
path: root/Objects/stringobject.c
diff options
context:
space:
mode:
authorFredrik Lundh <fredrik@pythonware.com>2006-05-25 16:46:54 (GMT)
committerFredrik Lundh <fredrik@pythonware.com>2006-05-25 16:46:54 (GMT)
commit0c71f88fc9da05517dae2d4c85a7dc059b3f1b4b (patch)
tree9dacc6c9532bf207ca554acfbcb086e51c658a4a /Objects/stringobject.c
parent44aa9f7139bb6e05756ca156a00ca2952761fe7e (diff)
downloadcpython-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.c23
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) {