forked from boostorg/regex
Regex: Backup and restore internal match_results when saving recursion backtracking info, as well as the state required to restore the recursion stack. Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3478#c1
This commit is contained in:
@ -547,7 +547,7 @@ private:
|
||||
void push_repeater_count(int i, repeater_count<BidiIterator>** s);
|
||||
void push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id);
|
||||
void push_non_greedy_repeat(const re_syntax_base* ps);
|
||||
void push_recursion(int idx, const re_syntax_base* p, results_type* presults);
|
||||
void push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2);
|
||||
void push_recursion_pop();
|
||||
void push_case_change(bool);
|
||||
|
||||
|
@ -130,11 +130,11 @@ struct saved_single_repeat : public saved_state
|
||||
template <class Results>
|
||||
struct saved_recursion : public saved_state
|
||||
{
|
||||
saved_recursion(int idx, const re_syntax_base* p, Results* pr)
|
||||
: saved_state(14), recursion_id(idx), preturn_address(p), results(*pr) {}
|
||||
saved_recursion(int idx, const re_syntax_base* p, Results* pr, Results* pr2)
|
||||
: saved_state(14), recursion_id(idx), preturn_address(p), internal_results(*pr), prior_results(*pr2) {}
|
||||
int recursion_id;
|
||||
const re_syntax_base* preturn_address;
|
||||
Results results;
|
||||
Results internal_results, prior_results;
|
||||
};
|
||||
|
||||
struct saved_change_case : public saved_state
|
||||
@ -354,7 +354,7 @@ inline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(st
|
||||
}
|
||||
|
||||
template <class BidiIterator, class Allocator, class traits>
|
||||
inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int idx, const re_syntax_base* p, results_type* presults)
|
||||
inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2)
|
||||
{
|
||||
saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
|
||||
--pmp;
|
||||
@ -364,7 +364,7 @@ inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int id
|
||||
pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
|
||||
--pmp;
|
||||
}
|
||||
(void) new (pmp)saved_recursion<results_type>(idx, p, presults);
|
||||
(void) new (pmp)saved_recursion<results_type>(idx, p, presults, presults2);
|
||||
m_backup_state = pmp;
|
||||
}
|
||||
|
||||
@ -1052,7 +1052,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
|
||||
{
|
||||
pstate = recursion_stack.back().preturn_address;
|
||||
*m_presult = recursion_stack.back().results;
|
||||
push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, &recursion_stack.back().results);
|
||||
push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);
|
||||
recursion_stack.pop_back();
|
||||
push_repeater_count(-(2 + index), &next_count);
|
||||
}
|
||||
@ -1075,8 +1075,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
|
||||
{
|
||||
BOOST_ASSERT(0 == recursion_stack.back().idx);
|
||||
pstate = recursion_stack.back().preturn_address;
|
||||
push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);
|
||||
*m_presult = recursion_stack.back().results;
|
||||
push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, &recursion_stack.back().results);
|
||||
recursion_stack.pop_back();
|
||||
return true;
|
||||
}
|
||||
@ -1763,8 +1763,9 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r)
|
||||
recursion_stack.push_back(recursion_info<results_type>());
|
||||
recursion_stack.back().idx = pmp->recursion_id;
|
||||
recursion_stack.back().preturn_address = pmp->preturn_address;
|
||||
recursion_stack.back().results = pmp->results;
|
||||
recursion_stack.back().results = pmp->prior_results;
|
||||
recursion_stack.back().location_of_start = position;
|
||||
*m_presult = pmp->internal_results;
|
||||
}
|
||||
boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
|
||||
m_backup_state = pmp;
|
||||
@ -1777,6 +1778,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r)
|
||||
saved_state* pmp = static_cast<saved_state*>(m_backup_state);
|
||||
if(!r)
|
||||
{
|
||||
*m_presult = recursion_stack.back().results;
|
||||
position = recursion_stack.back().location_of_start;
|
||||
recursion_stack.pop_back();
|
||||
}
|
||||
boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
|
||||
|
Reference in New Issue
Block a user