diff options
| author | ksss <[email protected]> | 2017-03-10 13:26:15 +0900 |
|---|---|---|
| committer | ksss <[email protected]> | 2017-03-10 13:26:15 +0900 |
| commit | 4b3e6cf1691da5a9c87ef4d55004f7ea8b3e383d (patch) | |
| tree | cf02a1e7d40cd92192f2446fdb18441fd994d6ab | |
| parent | c6e5659fec42b1c2ac39292a1ba2ee5852c66846 (diff) | |
| download | mruby-4b3e6cf1691da5a9c87ef4d55004f7ea8b3e383d.tar.gz mruby-4b3e6cf1691da5a9c87ef4d55004f7ea8b3e383d.zip | |
Avoid infinity loop when empty string pattern
| -rw-r--r-- | mrblib/string.rb | 25 | ||||
| -rw-r--r-- | test/t/string.rb | 1 |
2 files changed, 16 insertions, 10 deletions
diff --git a/mrblib/string.rb b/mrblib/string.rb index b13cfd69a..0f65c9c97 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -52,17 +52,22 @@ class String # ISO 15.2.10.5.18 def gsub(*args, &block) if args.size == 2 - s = "" - i = 0 - while j = index(args[0], i) - seplen = args[0].length - k = j + seplen - pre = self[0, j] - post = self[k, length-k] - s += self[i, j-i] + args[1].__sub_replace(pre, args[0], post) - i = k + pattern, replace = *args + plen = pattern.length + replace = replace.to_str + offset = 0 + result = [] + while found = index(pattern, offset) + result << self[offset, found - offset] + offset = found + plen + result << replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "") + if plen == 0 + result << self[offset, 1] + offset += 1 + end end - s + self[i, length-i] + result << self[offset..-1] if offset < length + result.join elsif args.size == 1 && block split(args[0], -1).join(block.call(args[0])) else diff --git a/test/t/string.rb b/test/t/string.rb index 442c95bf7..e39eefb60 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -365,6 +365,7 @@ assert('String#gsub', '15.2.10.5.18') do assert_equal('$$a$$', '##a##'.gsub('##'){|w| '$$' }, 'mruby/mruby#847 another case with block') assert_equal('A', 'a'.gsub('a', 'A')) assert_equal('A', 'a'.gsub('a'){|w| w.capitalize }) + assert_equal(".h.e.l.l.o.", "hello".gsub("", ".")) end assert('String#gsub with backslash') do |
