forked from boostorg/regex
Make backstep calculation non-recursive.
Refs https://github.com/boostorg/regex/pull/236.
This commit is contained in:
@ -974,7 +974,12 @@ template <class charT, class traits>
|
|||||||
int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)
|
int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)
|
||||||
{
|
{
|
||||||
typedef typename traits::char_class_type m_type;
|
typedef typename traits::char_class_type m_type;
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
int last_alternative_result = -1;
|
||||||
|
|
||||||
|
std::vector<std::tuple<int, re_syntax_base*>> stack;
|
||||||
|
|
||||||
while(state)
|
while(state)
|
||||||
{
|
{
|
||||||
switch(state->type)
|
switch(state->type)
|
||||||
@ -993,9 +998,28 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case syntax_element_endmark:
|
case syntax_element_endmark:
|
||||||
if((static_cast<re_brace*>(state)->index == -1)
|
if ((static_cast<re_brace*>(state)->index == -1)
|
||||||
|| (static_cast<re_brace*>(state)->index == -2))
|
|| (static_cast<re_brace*>(state)->index == -2))
|
||||||
return result;
|
{
|
||||||
|
// We've finished the calculation, check against any previous alternatives:
|
||||||
|
if (last_alternative_result >= 0)
|
||||||
|
{
|
||||||
|
if (last_alternative_result != result)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
last_alternative_result = result;
|
||||||
|
|
||||||
|
if (stack.size())
|
||||||
|
{
|
||||||
|
// Skip to next alternative and calculate that as well:
|
||||||
|
std::tie(result, state) = stack.back();
|
||||||
|
stack.pop_back();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return result;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case syntax_element_literal:
|
case syntax_element_literal:
|
||||||
result += static_cast<re_literal*>(state)->length;
|
result += static_cast<re_literal*>(state)->length;
|
||||||
@ -1051,11 +1075,13 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state
|
|||||||
continue;
|
continue;
|
||||||
case syntax_element_alt:
|
case syntax_element_alt:
|
||||||
{
|
{
|
||||||
int r1 = calculate_backstep(state->next.p);
|
// Push the alternative if we haven't pushed too many already:
|
||||||
int r2 = calculate_backstep(static_cast<re_alt*>(state)->alt.p);
|
if(stack.size() > BOOST_REGEX_MAX_BLOCKS)
|
||||||
if((r1 < 0) || (r1 != r2))
|
|
||||||
return -1;
|
return -1;
|
||||||
return result + r1;
|
stack.push_back(std::make_tuple(result, static_cast<re_alt*>(state)->alt.p));
|
||||||
|
// and take the first one:
|
||||||
|
state = state->next.p;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -137,3 +137,5 @@ compile test_windows_defs_4.cpp ;
|
|||||||
run issue153.cpp : : : "<toolset>msvc:<linkflags>-STACK:2097152" ;
|
run issue153.cpp : : : "<toolset>msvc:<linkflags>-STACK:2097152" ;
|
||||||
run issue227.cpp ;
|
run issue227.cpp ;
|
||||||
run issue232.cpp ;
|
run issue232.cpp ;
|
||||||
|
run lookbehind_recursion_stress_test.cpp ;
|
||||||
|
|
||||||
|
28
test/lookbehind_recursion_stress_test.cpp
Normal file
28
test/lookbehind_recursion_stress_test.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024
|
||||||
|
* John Maddock
|
||||||
|
*
|
||||||
|
* Use, modification and distribution are subject to the
|
||||||
|
* Boost Software License, Version 1.0. (See accompanying file
|
||||||
|
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::string s("(?<=(");
|
||||||
|
s.append(1000, '|');
|
||||||
|
s += "))";
|
||||||
|
boost::regex rx(s);
|
||||||
|
|
||||||
|
s = "(?<=(a";
|
||||||
|
for (unsigned i = 0; i < 1000; ++i)
|
||||||
|
{
|
||||||
|
s += "|a";
|
||||||
|
}
|
||||||
|
s += "))";
|
||||||
|
boost::regex rx2(s);
|
||||||
|
}
|
Reference in New Issue
Block a user