mirror of
https://github.com/boostorg/regex.git
synced 2025-07-23 00:57:19 +02:00
de-fuzz: prevent infinite recursion in recursive expressions (case 14).
This commit is contained in:
@ -348,6 +348,7 @@ struct recursion_info
|
||||
const re_syntax_base* preturn_address;
|
||||
Results results;
|
||||
repeater_count<iterator>* repeater_stack;
|
||||
iterator location_of_start;
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
|
@ -953,6 +953,19 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
|
||||
{
|
||||
BOOST_ASSERT(pstate->type == syntax_element_recurse);
|
||||
//
|
||||
// See if we've seen this recursion before at this location, if we have then
|
||||
// we need to prevent infinite recursion:
|
||||
//
|
||||
for(std::vector<recursion_info<results_type> >::const_reverse_iterator i = recursion_stack.rbegin(); i != recursion_stack.rend(); ++i)
|
||||
{
|
||||
if(i->idx == static_cast<const re_brace*>(static_cast<const re_jump*>(pstate)->alt.p)->index)
|
||||
{
|
||||
if(i->location_of_start == position)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Backup call stack:
|
||||
//
|
||||
push_recursion_pop();
|
||||
@ -968,6 +981,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
|
||||
recursion_stack.back().results = *m_presult;
|
||||
pstate = static_cast<const re_jump*>(pstate)->alt.p;
|
||||
recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;
|
||||
recursion_stack.back().location_of_start = position;
|
||||
//if(static_cast<const re_recurse*>(pstate)->state_id > 0)
|
||||
{
|
||||
push_repeater_count(-(2 + static_cast<const re_brace*>(pstate)->index), &next_count);
|
||||
|
@ -900,10 +900,27 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
|
||||
{
|
||||
recursion_stack.reserve(50);
|
||||
}
|
||||
//
|
||||
// See if we've seen this recursion before at this location, if we have then
|
||||
// we need to prevent infinite recursion:
|
||||
//
|
||||
for(std::vector<recursion_info<results_type> >::const_reverse_iterator i = recursion_stack.rbegin(); i != recursion_stack.rend(); ++i)
|
||||
{
|
||||
if(i->idx == static_cast<const re_brace*>(static_cast<const re_jump*>(pstate)->alt.p)->index)
|
||||
{
|
||||
if(i->location_of_start == position)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Now get on with it:
|
||||
//
|
||||
recursion_stack.push_back(recursion_info<results_type>());
|
||||
recursion_stack.back().preturn_address = pstate->next.p;
|
||||
recursion_stack.back().results = *m_presult;
|
||||
recursion_stack.back().repeater_stack = next_count;
|
||||
recursion_stack.back().location_of_start = position;
|
||||
pstate = static_cast<const re_jump*>(pstate)->alt.p;
|
||||
recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;
|
||||
|
||||
|
Reference in New Issue
Block a user