[regexp] Throw when length of text nodes in alternatives is too large.

Offsets in regular expressions are limited to 16 bits.
It was possible to exceed this limit when emitting greedy loops where
the length of text nodes exceeded 16 bits, resulting in overflowing
offsets.
With this CL we throw a SyntaxError "Regular expression too large" to
prevent this overflow.

Bug: chromium:1166138
Change-Id: Ica624a243bf9827083ff883d9a976f13c8da02e5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2629286
Commit-Queue: Patrick Thier <pthier@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72095}
This commit is contained in:
Patrick Thier 2021-01-14 14:15:09 +00:00 committed by Commit Bot
parent a358c2eb42
commit 3466daa7e4
3 changed files with 11 additions and 5 deletions

View File

@ -2537,7 +2537,16 @@ int ChoiceNode::GreedyLoopTextLengthForAlternative(
SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node);
node = seq_node->on_success();
}
return read_backward() ? -length : length;
if (read_backward()) {
length = -length;
}
// Check that we can jump by the whole text length. If not, return sentinel
// to indicate the we can't construct a greedy loop.
if (length < RegExpMacroAssembler::kMinCPOffset ||
length > RegExpMacroAssembler::kMaxCPOffset) {
return kNodeIsTooComplexForGreedyLoops;
}
return length;
}
void LoopChoiceNode::AddLoopAlternative(GuardedAlternative alt) {

View File

@ -73,9 +73,6 @@
# https://crbug.com/1129854
'tools/log': ['arch == arm or arch == arm64', SKIP],
# https://crbug.com/1166138
'regress/regress-1166138': SKIP,
##############################################################################
# Tests where variants make no sense.
'd8/enable-tracing': [PASS, NO_VARIANTS],

View File

@ -4,4 +4,4 @@
let badregexp = "(?:" + " ".repeat(32768*2)+ ")*";
reg = RegExp(badregexp);
reg.test()
assertThrows(() => reg.test(), SyntaxError);