@@ -974,7 +974,12 @@ template <class charT, class traits>
974
974
int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)
975
975
{
976
976
typedef typename traits::char_class_type m_type;
977
+
977
978
int result = 0 ;
979
+ int last_alternative_result = -1 ;
980
+
981
+ std::vector<std::tuple<int , re_syntax_base*>> stack;
982
+
978
983
while (state)
979
984
{
980
985
switch (state->type )
@@ -993,9 +998,28 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state
993
998
}
994
999
break ;
995
1000
case syntax_element_endmark:
996
- if ((static_cast <re_brace*>(state)->index == -1 )
1001
+ if ((static_cast <re_brace*>(state)->index == -1 )
997
1002
|| (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
+ }
999
1023
break ;
1000
1024
case syntax_element_literal:
1001
1025
result += static_cast <re_literal*>(state)->length ;
@@ -1051,11 +1075,13 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state
1051
1075
continue ;
1052
1076
case syntax_element_alt:
1053
1077
{
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)
1057
1080
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 ;
1059
1085
}
1060
1086
default :
1061
1087
break ;
0 commit comments