Skip to content

Commit 630d6be

Browse files
committed
[YARR] EOL string list optimization produces incorrect matches with multiline flag
https://bugs.webkit.org/show_bug.cgi?id=318333 Reviewed by Yusuke Suzuki. When the multiline flag is set, the EOL string list optimization produces incorrect matches: /^(?:a|a\nx)$/m.exec("a\nx") // actual(JIT): "a\nx", expected: "a" /^(?:a\nb|a)$/m.exec("a\nbQ") // actual(JIT): null, expected: "a" This patch fixes the bug by disabling the optimization when the multiline flag is set. Test: JSTests/stress/regexp-stringlist-eol-multiline.js * JSTests/stress/regexp-stringlist-eol-multiline.js: Added. (shouldBe): * Source/JavaScriptCore/yarr/YarrPattern.cpp: (JSC::Yarr::YarrPatternConstructor::checkForTerminalParentheses): Canonical link: https://commits.webkit.org/316345@main
1 parent f23ffb5 commit 630d6be

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function shouldBe(actual, expected) {
2+
if (actual !== expected)
3+
throw new Error('bad value: ' + actual + ', expected: ' + expected);
4+
}
5+
6+
// Alternation must prefer the earlier alternative "a", which matches because
7+
// multiline $ succeeds before the line terminator.
8+
shouldBe(/^(?:a|a\nx)$/m.exec("a\nx")[0], "a");
9+
shouldBe(/^(?:a|a\nx)$/m.test("a\nx"), true);
10+
11+
// "a\nb" matches the text but fails $ (next char is "Q"); the later
12+
// alternative "a" must then be tried and succeeds before the "\n".
13+
shouldBe(/^(?:a\nb|a)$/m.exec("a\nbQ")[0], "a");
14+
15+
shouldBe(/^(?:foo|bar|f)$/m.exec("foo")[0], "foo");
16+
shouldBe(/^(?:foo|bar|f)$/m.exec("bar\nzzz")[0], "bar");
17+
shouldBe(/^(?:foo|bar|f)$/m.exec("f\nbar")[0], "f");
18+
shouldBe(/^(?:foo|bar|f)$/m.exec("fo"), null);

‎Source/JavaScriptCore/yarr/YarrPattern.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2084,7 +2084,7 @@ class YarrPatternConstructor {
20842084
&& terms[1].quantityMaxCount == 1
20852085
&& !terms[1].parentheses.isCopy
20862086
&& (terms.size() == 2
2087-
|| (terms.size() == 3 && terms[2].type == PatternTerm::Type::AssertionEOL))) {
2087+
|| (terms.size() == 3 && terms[2].type == PatternTerm::Type::AssertionEOL && !m_pattern.multiline()))) {
20882088
// We start assuming this is a string list and then prove the negative.
20892089
isStringList = true;
20902090

0 commit comments

Comments
 (0)