Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1526)

Unified Diff: src/jsregexp.cc

Issue 12380026: Limit EatAtLeast recursion by a budget. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/jsregexp.cc
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 9b82da131cf44ffae8334a54e8a0ee50df157cae..a82a6c107e5e5525f54f79c8c92d47b302755de2 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -2299,35 +2299,33 @@ RegExpNode::LimitResult RegExpNode::LimitVersions(RegExpCompiler* compiler,
int ActionNode::EatsAtLeast(int still_to_find,
- int recursion_depth,
+ int budget,
bool not_at_start) {
- if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
+ if (budget <= 0) return 0;
if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input!
return on_success()->EatsAtLeast(still_to_find,
- recursion_depth + 1,
+ budget - 1,
not_at_start);
}
void ActionNode::FillInBMInfo(int offset,
- int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
if (type_ == BEGIN_SUBMATCH) {
bm->SetRest(offset);
} else if (type_ != POSITIVE_SUBMATCH_SUCCESS) {
- on_success()->FillInBMInfo(
- offset, recursion_depth + 1, budget - 1, bm, not_at_start);
+ on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
}
SaveBMInfo(bm, not_at_start, offset);
}
int AssertionNode::EatsAtLeast(int still_to_find,
- int recursion_depth,
+ int budget,
bool not_at_start) {
- if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
+ if (budget <= 0) return 0;
// If we know we are not at the start and we are asked "how many characters
// will you match if you succeed?" then we can answer anything since false
// implies false. So lets just return the max answer (still_to_find) since
@@ -2335,55 +2333,53 @@ int AssertionNode::EatsAtLeast(int still_to_find,
// branches in the node graph.
if (type() == AT_START && not_at_start) return still_to_find;
return on_success()->EatsAtLeast(still_to_find,
- recursion_depth + 1,
+ budget - 1,
not_at_start);
}
void AssertionNode::FillInBMInfo(int offset,
- int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
// Match the behaviour of EatsAtLeast on this node.
if (type() == AT_START && not_at_start) return;
- on_success()->FillInBMInfo(
- offset, recursion_depth + 1, budget - 1, bm, not_at_start);
+ on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
SaveBMInfo(bm, not_at_start, offset);
}
int BackReferenceNode::EatsAtLeast(int still_to_find,
- int recursion_depth,
+ int budget,
bool not_at_start) {
- if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
+ if (budget <= 0) return 0;
return on_success()->EatsAtLeast(still_to_find,
- recursion_depth + 1,
+ budget - 1,
not_at_start);
}
int TextNode::EatsAtLeast(int still_to_find,
- int recursion_depth,
+ int budget,
bool not_at_start) {
int answer = Length();
if (answer >= still_to_find) return answer;
- if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer;
+ if (budget <= 0) return answer;
// We are not at start after this node so we set the last argument to 'true'.
return answer + on_success()->EatsAtLeast(still_to_find - answer,
- recursion_depth + 1,
+ budget - 1,
true);
}
int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find,
- int recursion_depth,
+ int budget,
bool not_at_start) {
- if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
+ if (budget <= 0) return 0;
// Alternative 0 is the negative lookahead, alternative 1 is what comes
// afterwards.
RegExpNode* node = alternatives_->at(1).node();
- return node->EatsAtLeast(still_to_find, recursion_depth + 1, not_at_start);
+ return node->EatsAtLeast(still_to_find, budget - 1, not_at_start);
}
@@ -2400,39 +2396,40 @@ void NegativeLookaheadChoiceNode::GetQuickCheckDetails(
int ChoiceNode::EatsAtLeastHelper(int still_to_find,
- int recursion_depth,
+ int budget,
RegExpNode* ignore_this_node,
bool not_at_start) {
- if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
+ if (budget <= 0) return 0;
int min = 100;
int choice_count = alternatives_->length();
+ budget = (budget - 1) / choice_count;
for (int i = 0; i < choice_count; i++) {
RegExpNode* node = alternatives_->at(i).node();
if (node == ignore_this_node) continue;
- int node_eats_at_least = node->EatsAtLeast(still_to_find,
- recursion_depth + 1,
- not_at_start);
+ int node_eats_at_least =
+ node->EatsAtLeast(still_to_find, budget, not_at_start);
if (node_eats_at_least < min) min = node_eats_at_least;
+ if (min == 0) return 0;
}
return min;
}
int LoopChoiceNode::EatsAtLeast(int still_to_find,
- int recursion_depth,
+ int budget,
bool not_at_start) {
return EatsAtLeastHelper(still_to_find,
- recursion_depth,
+ budget - 1,
loop_node_,
not_at_start);
}
int ChoiceNode::EatsAtLeast(int still_to_find,
- int recursion_depth,
+ int budget,
bool not_at_start) {
return EatsAtLeastHelper(still_to_find,
- recursion_depth,
+ budget,
NULL,
not_at_start);
}
@@ -2988,19 +2985,15 @@ void LoopChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
void LoopChoiceNode::FillInBMInfo(int offset,
- int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
- if (body_can_be_zero_length_ ||
- recursion_depth > RegExpCompiler::kMaxRecursion ||
- budget <= 0) {
+ if (body_can_be_zero_length_ || budget <= 0) {
bm->SetRest(offset);
SaveBMInfo(bm, not_at_start, offset);
return;
}
- ChoiceNode::FillInBMInfo(
- offset, recursion_depth + 1, budget - 1, bm, not_at_start);
+ ChoiceNode::FillInBMInfo(offset, budget - 1, bm, not_at_start);
SaveBMInfo(bm, not_at_start, offset);
}
@@ -3097,12 +3090,13 @@ void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) {
BoyerMooreLookahead* lookahead = bm_info(not_at_start);
if (lookahead == NULL) {
int eats_at_least =
- Min(kMaxLookaheadForBoyerMoore,
- EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start));
+ Min(kMaxLookaheadForBoyerMoore, EatsAtLeast(kMaxLookaheadForBoyerMoore,
+ kFillInBMBudget,
+ not_at_start));
if (eats_at_least >= 1) {
BoyerMooreLookahead* bm =
new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone());
- FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start);
+ FillInBMInfo(0, kFillInBMBudget, bm, not_at_start);
if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE;
}
@@ -4034,16 +4028,17 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes.
BoyerMooreLookahead* lookahead = bm_info(not_at_start);
if (lookahead == NULL) {
- eats_at_least =
- Min(kMaxLookaheadForBoyerMoore,
- EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start));
+ eats_at_least = Min(kMaxLookaheadForBoyerMoore,
+ EatsAtLeast(kMaxLookaheadForBoyerMoore,
+ kFillInBMBudget,
+ not_at_start));
if (eats_at_least >= 1) {
BoyerMooreLookahead* bm =
new(zone()) BoyerMooreLookahead(eats_at_least,
compiler,
zone());
GuardedAlternative alt0 = alternatives_->at(0);
- alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start);
+ alt0.node()->FillInBMInfo(0, kFillInBMBudget, bm, not_at_start);
skip_was_emitted = bm->EmitSkipInstructions(macro_assembler);
}
} else {
@@ -4055,7 +4050,8 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
if (eats_at_least == kEatsAtLeastNotYetInitialized) {
// Save some time by looking at most one machine word ahead.
- eats_at_least = EatsAtLeast(compiler->ascii() ? 4 : 2, 0, not_at_start);
+ eats_at_least =
+ EatsAtLeast(compiler->ascii() ? 4 : 2, kFillInBMBudget, not_at_start);
}
int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least);
@@ -5811,7 +5807,6 @@ void Analysis::VisitAssertion(AssertionNode* that) {
void BackReferenceNode::FillInBMInfo(int offset,
- int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
@@ -5827,7 +5822,6 @@ STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize ==
void ChoiceNode::FillInBMInfo(int offset,
- int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
@@ -5840,15 +5834,13 @@ void ChoiceNode::FillInBMInfo(int offset,
SaveBMInfo(bm, not_at_start, offset);
return;
}
- alt.node()->FillInBMInfo(
- offset, recursion_depth + 1, budget, bm, not_at_start);
+ alt.node()->FillInBMInfo(offset, budget, bm, not_at_start);
}
SaveBMInfo(bm, not_at_start, offset);
}
void TextNode::FillInBMInfo(int initial_offset,
- int recursion_depth,
int budget,
BoyerMooreLookahead* bm,
bool not_at_start) {
@@ -5905,7 +5897,6 @@ void TextNode::FillInBMInfo(int initial_offset,
return;
}
on_success()->FillInBMInfo(offset,
- recursion_depth + 1,
budget - 1,
bm,
true); // Not at start after a text node.

Powered by Google App Engine
This is Rietveld 408576698