Skip to content

Commit 075625c

Browse files
committed
avoiding infinite loop in String#gsub when there is a zero length match
1 parent 2a69140 commit 075625c

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

src/prototype/lang/string.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ Object.extend(String.prototype, (function() {
100100
}
101101

102102
while (source.length > 0) {
103-
if (match = source.match(pattern)) {
103+
match = source.match(pattern)
104+
if (match && match[0].length > 0) {
104105
result += source.slice(0, match.index);
105106
result += String.interpret(replacement(match));
106107
source = source.slice(match.index + match[0].length);

test/unit/string_test.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ new Test.Unit.Runner({
6666

6767
testGsubWithTroublesomeCharacters: function() {
6868
this.assertEqual('ab', 'a|b'.gsub('|', ''));
69-
//'ab'.gsub('', ''); // freeze
7069
this.assertEqual('ab', 'ab(?:)'.gsub('(?:)', ''));
7170
this.assertEqual('ab', 'ab()'.gsub('()', ''));
7271
this.assertEqual('ab', 'ab'.gsub('^', ''));
@@ -77,6 +76,12 @@ new Test.Unit.Runner({
7776
this.assertEqual('ab', 'a.b'.gsub('.', ''));
7877
},
7978

79+
testGsubWithZeroLengthMatch: function() {
80+
this.assertEqual('ab', 'ab'.gsub('', ''));
81+
this.assertEqual('a', 'a'.gsub(/b*/, 'c'));
82+
this.assertEqual('abc', 'abc'.gsub(/b{0}/, ''));
83+
},
84+
8085
testSubWithReplacementFunction: function() {
8186
var source = 'foo boo boz';
8287

0 commit comments

Comments
 (0)