[Webkit-unassigned] [Bug 26890] String.prototype.match and replace do not clear global regexp lastIndex per ES5.1 15.5.4.10

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Wed Mar 7 22:27:52 PST 2012


https://bugs.webkit.org/show_bug.cgi?id=26890





--- Comment #2 from Gavin Barraclough <barraclough at apple.com>  2012-03-07 22:27:51 PST ---
Gah, premature commit!  Anyway, we definitely have a bug here, but I think the spec may actually call for slightly different expected results.

The spec requires that match first clears lastIndex, then calls exec until it returns null (per 15.5.4.10 8.f.ii).  When exec returns null, it also clears lastIndex (per 15.10.6.2 step 9.a.1).  So after a match, the value of lastIndex must be 0.  Our implementation of match ignores and does not update lastIndex.  Ignoring its initial value is correct, failing to reset it isn't.

var s = '0x2x4x6x8';
var p = /x/g;
p.lastIndex = 3;
s.match(p);
print(p.lastIndex); // prints 3, should be 0 after a match.

Similarly, after a replace without a callback replacer function, the lastIndex should definitely be reset.

var s = '0x2x4x6x8';
var p = /x/g;
p.lastIndex = 3;
s.replace(p,'y');
print(p.lastIndex); // prints 3, should be 0 after a replace.

The spec does not enumerate the stages of performing a replace as clearly as it does for some library functions, but it contains the following two directions:

firstly: "If searchValue.global is true, then search string for all matches of the regular expression searchValue. Do the search in the same manner as in String.prototype.match, including the update of searchValue.lastIndex."
secondly: "If replaceValue is a function, then for each matched substring, call the function"

This clearly implies that these actions should take place in the following order:
1) Find all match results
2) Set the value of lastIndex to 0 (implicitly performed by 15.10.6.2 step 9.a.1 called via the action of the last iteration of 15.5.4.10 8.f.i).
3) Call all replacers.

As such, the replace method should set lastIndex to 0 once, before any replacers are called, and then not change the value.

var s = '0x1x2x3x4';
var p = /x/g;
p.lastIndex = 5;
s.replace(p, function() { return ++p.lastIndex; })
// should be "011223344"

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the webkit-unassigned mailing list