[regexp] Fix numbered reference before named capture
Numbered back-references that occur before the referenced capture trigger an internal mini-parser that looks ahead in the pattern and counts capturing groups. This updates the mini-parser to correctly handle named captures. BUG=v8:5437 Review-Url: https://codereview.chromium.org/2792523002 Cr-Commit-Position: refs/heads/master@{#44303}
This commit is contained in:
parent
d6bd3ebaea
commit
3f8b2aeb35
@ -680,7 +680,25 @@ void RegExpParser::ScanForCaptures() {
|
||||
break;
|
||||
}
|
||||
case '(':
|
||||
if (current() != '?') capture_count++;
|
||||
if (current() == '?') {
|
||||
// At this point we could be in
|
||||
// * a non-capturing group '(:',
|
||||
// * a lookbehind assertion '(?<=' '(?<!'
|
||||
// * or a named capture '(?<'.
|
||||
//
|
||||
// Of these, only named captures are capturing groups.
|
||||
if (!FLAG_harmony_regexp_named_captures) break;
|
||||
|
||||
Advance();
|
||||
if (current() != '<') break;
|
||||
|
||||
// TODO(jgruber): To be more future-proof we could test for
|
||||
// IdentifierStart here once it becomes clear whether group names
|
||||
// allow unicode escapes.
|
||||
Advance();
|
||||
if (current() == '=' || current() == '!') break;
|
||||
}
|
||||
capture_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +124,12 @@ assertEquals(["fst", "snd"],
|
||||
assertEquals(undefined, /(?<a>.)/u.exec("a").groups.__proto__);
|
||||
assertEquals("a", /(?<__proto__>a)/u.exec("a").groups.__proto__);
|
||||
|
||||
// Backreference before the group (exercises the capture mini-parser).
|
||||
assertThrows("/\\1(?:.)/u", SyntaxError);
|
||||
assertThrows("/\\1(?<=a)./u", SyntaxError);
|
||||
assertThrows("/\\1(?<!a)./u", SyntaxError);
|
||||
assertEquals(["a", "a"], /\1(?<a>.)/u.exec("abcd"));
|
||||
|
||||
// @@replace with a callable replacement argument (no named captures).
|
||||
{
|
||||
let result = "abcd".replace(/(.)(.)/u, (match, fst, snd, offset, str) => {
|
||||
|
Loading…
Reference in New Issue
Block a user