@@ -974,7 +974,12 @@ template <class charT, class traits>
974974int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)
975975{
976976 typedef typename traits::char_class_type m_type;
977+
977978 int result = 0 ;
979+ int last_alternative_result = -1 ;
980+
981+ std::vector<std::tuple<int , re_syntax_base*>> stack;
982+
978983 while (state)
979984 {
980985 switch (state->type )
@@ -993,9 +998,28 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state
993998 }
994999 break ;
9951000 case syntax_element_endmark:
996- if ((static_cast <re_brace*>(state)->index == -1 )
1001+ if ((static_cast <re_brace*>(state)->index == -1 )
9971002 || (static_cast <re_brace*>(state)->index == -2 ))
998- return result;
1003+ {
1004+ // We've finished the calculation, check against any previous alternatives:
1005+ if (last_alternative_result >= 0 )
1006+ {
1007+ if (last_alternative_result != result)
1008+ return -1 ;
1009+ }
1010+ else
1011+ last_alternative_result = result;
1012+
1013+ if (stack.size ())
1014+ {
1015+ // Skip to next alternative and calculate that as well:
1016+ std::tie (result, state) = stack.back ();
1017+ stack.pop_back ();
1018+ continue ;
1019+ }
1020+ else
1021+ return result;
1022+ }
9991023 break ;
10001024 case syntax_element_literal:
10011025 result += static_cast <re_literal*>(state)->length ;
@@ -1051,11 +1075,13 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state
10511075 continue ;
10521076 case syntax_element_alt:
10531077 {
1054- int r1 = calculate_backstep (state->next .p );
1055- int r2 = calculate_backstep (static_cast <re_alt*>(state)->alt .p );
1056- if ((r1 < 0 ) || (r1 != r2))
1078+ // Push the alternative if we haven't pushed too many already:
1079+ if (stack.size () > BOOST_REGEX_MAX_BLOCKS)
10571080 return -1 ;
1058- return result + r1;
1081+ stack.push_back (std::make_tuple (result, static_cast <re_alt*>(state)->alt .p ));
1082+ // and take the first one:
1083+ state = state->next .p ;
1084+ continue ;
10591085 }
10601086 default :
10611087 break ;
0 commit comments