summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-08-23 18:50:21 (GMT)
committerGuido van Rossum <guido@python.org>2002-08-23 18:50:21 (GMT)
commit2023c9b84a08f96a8786c8e87625b00074de21a2 (patch)
tree3fa1fd400cf04a2084fe12e42f55c91e69b227fa
parent8b1a6d694fa2f38cde77892c5ee0bb177be49db6 (diff)
downloadcpython-2023c9b84a08f96a8786c8e87625b00074de21a2.zip
cpython-2023c9b84a08f96a8786c8e87625b00074de21a2.tar.gz
cpython-2023c9b84a08f96a8786c8e87625b00074de21a2.tar.bz2
Fix SF bug 599128, submitted by Inyeol Lee: .replace() would do the
wrong thing for a unicode subclass when there were zero string replacements. The example given in the SF bug report was only one way to trigger this; replacing a string of length >= 2 that's not found is another. The code would actually write outside allocated memory if replacement string was longer than the search string. (I wonder how many more of these are lurking? The unicode code base is full of wonders.) Bugfix candidate; this same bug is present in 2.2.1.
-rw-r--r--Lib/test/test_unicode.py2
-rw-r--r--Objects/unicodeobject.c12
2 files changed, 11 insertions, 3 deletions
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 90147eb..9e36316 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -213,6 +213,8 @@ test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@', 2)
test('replace', u'abc', u'-a-b-c-', u'', u'-')
test('replace', u'abc', u'-a-b-c', u'', u'-', 3)
test('replace', u'abc', u'abc', u'', u'-', 0)
+test('replace', u'abc', u'abc', u'ab', u'--', 0)
+test('replace', u'abc', u'abc', u'xy', u'--')
test('replace', u'', u'', u'', u'')
test('startswith', u'hello', True, u'he')
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 6dea94f..920f9ea 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -3534,10 +3534,16 @@ PyObject *replace(PyUnicodeObject *self,
n = count(self, 0, self->length, str1);
if (n > maxcount)
n = maxcount;
- if (n == 0 && PyUnicode_CheckExact(self)) {
+ if (n == 0) {
/* nothing to replace, return original string */
- Py_INCREF(self);
- u = self;
+ if (PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ u = self;
+ }
+ else {
+ u = (PyUnicodeObject *)
+ PyUnicode_FromUnicode(self->str, self->length);
+ }
} else {
u = _PyUnicode_New(
self->length + n * (str2->length - str1->length));