From 1a7b3eee946183c75eddecafe76c60e87c6f5e7d Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Wed, 9 May 2001 23:00:26 +0000 Subject: SF bug #422088: [OSF1 alpha] string.replace(). Platform blew up on "123".replace("123", ""). Michael Hudson pinned the blame on platform malloc(0) returning NULL. This is a candidate for all bugfix releases. --- Lib/test/string_tests.py | 6 +++++ Modules/stropmodule.c | 59 +++++++++++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index a408ef3..fcce50f 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -177,6 +177,12 @@ def run_method_tests(test): test('replace', 'one!two!three!', 'one@two@three@', '!', '@') test('replace', 'one!two!three!', 'one!two!three!', 'x', '@') test('replace', 'one!two!three!', 'one!two!three!', 'x', '@', 2) + # Next three for SF bug 422088: [OSF1 alpha] string.replace(); died with + # MemoryError due to empty result (platform malloc issue when requesting + # 0 bytes). + test('replace', '123', '', '123', '') + test('replace', '123123', '', '123', '') + test('replace', '123x123', 'x', '123', '') test('startswith', 'hello', 1, 'he') test('startswith', 'hello', 1, 'hello') diff --git a/Modules/stropmodule.c b/Modules/stropmodule.c index af5aa77..b92cb01 100644 --- a/Modules/stropmodule.c +++ b/Modules/stropmodule.c @@ -1061,36 +1061,43 @@ mymemreplace(char *str, int len, nfound = nfound > count ? count : nfound; if (nfound == 0) goto return_same; + new_len = len + nfound*(sub_len - pat_len); + if (new_len == 0) { + out_s = ""; + } + else { + assert(new_len > 0); + new_s = (char *)PyMem_MALLOC(new_len); + if (new_s == NULL) + return NULL; + out_s = new_s; - new_s = (char *)PyMem_MALLOC(new_len); - if (new_s == NULL) return NULL; + while (len > 0) { + /* find index of next instance of pattern */ + offset = mymemfind(str, len, pat, pat_len); + if (offset == -1) + break; - *out_len = new_len; - out_s = new_s; - - while (len > 0) { - /* find index of next instance of pattern */ - offset = mymemfind(str, len, pat, pat_len); - /* if not found, break out of loop */ - if (offset == -1) break; - - /* copy non matching part of input string */ - memcpy(new_s, str, offset); /* copy part of str before pat */ - str += offset + pat_len; /* move str past pattern */ - len -= offset + pat_len; /* reduce length of str remaining */ - - /* copy substitute into the output string */ - new_s += offset; /* move new_s to dest for sub string */ - memcpy(new_s, sub, sub_len); /* copy substring into new_s */ - new_s += sub_len; /* offset new_s past sub string */ - - /* break when we've done count replacements */ - if (--count == 0) break; + /* copy non matching part of input string */ + memcpy(new_s, str, offset); + str += offset + pat_len; + len -= offset + pat_len; + + /* copy substitute into the output string */ + new_s += offset; + memcpy(new_s, sub, sub_len); + new_s += sub_len; + + /* note count==0 is effectively infinity */ + if (--count == 0) + break; + } + /* copy any remaining values into output string */ + if (len > 0) + memcpy(new_s, str, len); } - /* copy any remaining values into output string */ - if (len > 0) - memcpy(new_s, str, len); + *out_len = new_len; return out_s; return_same: -- cgit v0.12