]> granicus.if.org Git - python/commitdiff
Fixed problem identified by Georg. The special-case in-place code for replace
authorAndrew Dalke <dalke@dalkescientific.com>
Thu, 25 May 2006 17:53:00 +0000 (17:53 +0000)
committerAndrew Dalke <dalke@dalkescientific.com>
Thu, 25 May 2006 17:53:00 +0000 (17:53 +0000)
made a copy of the string using PyString_FromStringAndSize(s, n) and modify
the copied string in-place.  However, 1 (and 0) character strings are shared
from a cache.  This cause "A".replace("A", "a") to change the cached version
of "A" -- used by everyone.

Now may the copy with NULL as the string and do the memcpy manually.  I've
added regression tests to check if this happens in the future.  Perhaps
there should be a PyString_Copy for this case?

Objects/stringobject.c

index aed0c2361879387aabb9ffd4c969f347bef08cbb..b0c4640a0cb252a05bd877071acc1dc83cca421e 100644 (file)
@@ -2692,10 +2692,11 @@ replace_single_character_in_place(PyStringObject *self,
        }
        
        /* Need to make a new string */
-       result = (PyStringObject *) PyString_FromStringAndSize(self_s, self_len);
+       result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
        if (result == NULL)
                return NULL;
        result_s = PyString_AS_STRING(result);
+       memcpy(result_s, self_s, self_len);
        
        /* change everything in-place, starting with this one */
        start =  result_s + (next-self_s);
@@ -2745,10 +2746,12 @@ replace_substring_in_place(PyStringObject *self,
        }
        
        /* Need to make a new string */
-       result = (PyStringObject *) PyString_FromStringAndSize(self_s, self_len);
+       result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
        if (result == NULL)
                return NULL;
        result_s = PyString_AS_STRING(result);
+       memcpy(result_s, self_s, self_len);
+
        
        /* change everything in-place, starting with this one */
        start =  result_s + offset;