[pypy-svn] r58928 - in pypy/branch/2.5-merge/pypy/objspace/std: . test

iko at codespeak.net iko at codespeak.net
Fri Oct 10 19:31:13 CEST 2008


Author: iko
Date: Fri Oct 10 19:31:12 2008
New Revision: 58928

Modified:
   pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py
   pypy/branch/2.5-merge/pypy/objspace/std/test/test_stringobject.py
Log:
(iko, cfbolz)
raise OverflowError on replace when the result is too large



Modified: pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py	Fri Oct 10 19:31:12 2008
@@ -260,16 +260,9 @@
 
     return space.newlist(res_w)
 
-
-def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1):
-    maxsplit = space.int_w(w_maxsplit)
+def _split_helper(space, value, sep, maxsplit):
     res_w = []
     start = 0
-    value = w_self._value
-    by = w_by._value
-    bylen = len(by)
-    if bylen == 0:
-        raise OperationError(space.w_ValueError, space.wrap("empty separator"))
 
     while maxsplit != 0:
         next = value.find(by, start)
@@ -278,9 +271,18 @@
         res_w.append(sliced(space, value, start, next))
         start = next + bylen
         maxsplit -= 1   # NB. if it's already < 0, it stays < 0
-
+    
     res_w.append(sliced(space, value, start, len(value)))
 
+def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1):
+    maxsplit = space.int_w(w_maxsplit)
+    value = w_self._value
+    by = w_by._value
+    bylen = len(by)
+    if bylen == 0:
+        raise OperationError(space.w_ValueError, space.wrap("empty separator"))
+
+    res_w = _split_helper(space, value, by, maxsplit)
     return space.newlist(res_w)
 
 def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1):
@@ -485,22 +487,24 @@
         if maxsplit > 0 and maxsplit < upper + 2:
             upper = maxsplit - 1
             assert upper >= 0
-        substrings = [""]
+        substrings_w = [""]
         for i in range(upper):
             c = input[i]
-            substrings.append(c)
-        substrings.append(input[upper:])
-        return space.wrap(by.join(substrings))
-    startidx = 0
-    substrings = []
-    foundidx = input.find(sub, startidx)
-    while foundidx >= 0 and maxsplit != 0:
-        substrings.append(input[startidx:foundidx])
-        startidx = foundidx + len(sub)        
-        foundidx = input.find(sub, startidx)
-        maxsplit = maxsplit - 1
-    substrings.append(input[startidx:])
-    return space.wrap(by.join(substrings))
+            substrings_w.append(c)
+        substrings_w.append(input[upper:])
+    else:
+        substrings_w = _split_helper(space, input, sub, maxsplit)
+        
+    try:
+        # XXX conservative estimate. If your strings are that close
+        # to overflowing, bad luck.
+        ovfcheck(len(substrings_w) * len(by) + len(input))
+    except OverflowError:
+        raise OperationError(
+            space.w_OverflowError, 
+            space.wrap("replace string is too long"))
+    
+    return space.wrap(by.join(substrings_w))
 
 def _strip(space, w_self, w_chars, left, right):
     "internal function called by str_xstrip methods"

Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_stringobject.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/std/test/test_stringobject.py	(original)
+++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_stringobject.py	Fri Oct 10 19:31:12 2008
@@ -714,6 +714,13 @@
                 assert x.rstrip(y) == ''
                 assert x.lstrip(y) == ''
 
+    def test_replace_overflow(self):
+        import sys
+        if sys.maxint > 2**31-1:
+            skip("Wrong platform")
+        s = "a" * (2**16)
+        raises(OverflowError, s.replace, "", s)
+
 class AppTestPrebuilt(AppTestStringObject):
     def setup_class(cls):
         cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True})



More information about the Pypy-commit mailing list