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_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_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_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_recursion_pop();
|
||||||
void push_case_change(bool);
|
void push_case_change(bool);
|
||||||
|
|
||||||
|
@ -130,11 +130,11 @@ struct saved_single_repeat : public saved_state
|
|||||||
template <class Results>
|
template <class Results>
|
||||||
struct saved_recursion : public saved_state
|
struct saved_recursion : public saved_state
|
||||||
{
|
{
|
||||||
saved_recursion(int idx, const re_syntax_base* 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), results(*pr) {}
|
: saved_state(14), recursion_id(idx), preturn_address(p), internal_results(*pr), prior_results(*pr2) {}
|
||||||
int recursion_id;
|
int recursion_id;
|
||||||
const re_syntax_base* preturn_address;
|
const re_syntax_base* preturn_address;
|
||||||
Results results;
|
Results internal_results, prior_results;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct saved_change_case : public saved_state
|
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>
|
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);
|
saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
|
||||||
--pmp;
|
--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 = static_cast<saved_recursion<results_type>*>(m_backup_state);
|
||||||
--pmp;
|
--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;
|
m_backup_state = pmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1052,7 +1052,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
|
|||||||
{
|
{
|
||||||
pstate = recursion_stack.back().preturn_address;
|
pstate = 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);
|
push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);
|
||||||
recursion_stack.pop_back();
|
recursion_stack.pop_back();
|
||||||
push_repeater_count(-(2 + index), &next_count);
|
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);
|
BOOST_ASSERT(0 == recursion_stack.back().idx);
|
||||||
pstate = recursion_stack.back().preturn_address;
|
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;
|
*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();
|
recursion_stack.pop_back();
|
||||||
return true;
|
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.push_back(recursion_info<results_type>());
|
||||||
recursion_stack.back().idx = pmp->recursion_id;
|
recursion_stack.back().idx = pmp->recursion_id;
|
||||||
recursion_stack.back().preturn_address = pmp->preturn_address;
|
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;
|
recursion_stack.back().location_of_start = position;
|
||||||
|
*m_presult = pmp->internal_results;
|
||||||
}
|
}
|
||||||
boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
|
boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
|
||||||
m_backup_state = 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);
|
saved_state* pmp = static_cast<saved_state*>(m_backup_state);
|
||||||
if(!r)
|
if(!r)
|
||||||
{
|
{
|
||||||
|
*m_presult = recursion_stack.back().results;
|
||||||
|
position = recursion_stack.back().location_of_start;
|
||||||
recursion_stack.pop_back();
|
recursion_stack.pop_back();
|
||||||
}
|
}
|
||||||
boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
|
boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);
|
||||||
|
Reference in New Issue
Block a user