@@ -863,7 +863,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
863863 /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
864864 TRACE (("|%p|%p|BRANCH\n" , pattern , ptr ));
865865 LASTMARK_SAVE ();
866- if (state -> repeat )
866+ if (state -> save_marks )
867867 MARK_PUSH (ctx -> lastmark );
868868 for (; pattern [0 ]; pattern += pattern [0 ]) {
869869 if (pattern [1 ] == SRE_OP_LITERAL &&
@@ -878,16 +878,16 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
878878 state -> ptr = ptr ;
879879 DO_JUMP (JUMP_BRANCH , jump_branch , pattern + 1 );
880880 if (ret ) {
881- if (state -> repeat )
881+ if (state -> save_marks )
882882 MARK_POP_DISCARD (ctx -> lastmark );
883883 RETURN_ON_ERROR (ret );
884884 RETURN_SUCCESS ;
885885 }
886- if (state -> repeat )
886+ if (state -> save_marks )
887887 MARK_POP_KEEP (ctx -> lastmark );
888888 LASTMARK_RESTORE ();
889889 }
890- if (state -> repeat )
890+ if (state -> save_marks )
891891 MARK_POP_DISCARD (ctx -> lastmark );
892892 RETURN_FAILURE ;
893893
@@ -933,7 +933,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
933933 }
934934
935935 LASTMARK_SAVE ();
936- if (state -> repeat )
936+ if (state -> save_marks )
937937 MARK_PUSH (ctx -> lastmark );
938938
939939 if (pattern [pattern [0 ]] == SRE_OP_LITERAL ) {
@@ -952,19 +952,19 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
952952 DO_JUMP (JUMP_REPEAT_ONE_1 , jump_repeat_one_1 ,
953953 pattern + pattern [0 ]);
954954 if (ret ) {
955- if (state -> repeat )
955+ if (state -> save_marks )
956956 MARK_POP_DISCARD (ctx -> lastmark );
957957 RETURN_ON_ERROR (ret );
958958 RETURN_SUCCESS ;
959959 }
960- if (state -> repeat )
960+ if (state -> save_marks )
961961 MARK_POP_KEEP (ctx -> lastmark );
962962 LASTMARK_RESTORE ();
963963
964964 ptr -- ;
965965 ctx -> count -- ;
966966 }
967- if (state -> repeat )
967+ if (state -> save_marks )
968968 MARK_POP_DISCARD (ctx -> lastmark );
969969 } else {
970970 /* general case */
@@ -973,19 +973,19 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
973973 DO_JUMP (JUMP_REPEAT_ONE_2 , jump_repeat_one_2 ,
974974 pattern + pattern [0 ]);
975975 if (ret ) {
976- if (state -> repeat )
976+ if (state -> save_marks )
977977 MARK_POP_DISCARD (ctx -> lastmark );
978978 RETURN_ON_ERROR (ret );
979979 RETURN_SUCCESS ;
980980 }
981- if (state -> repeat )
981+ if (state -> save_marks )
982982 MARK_POP_KEEP (ctx -> lastmark );
983983 LASTMARK_RESTORE ();
984984
985985 ptr -- ;
986986 ctx -> count -- ;
987987 }
988- if (state -> repeat )
988+ if (state -> save_marks )
989989 MARK_POP_DISCARD (ctx -> lastmark );
990990 }
991991 RETURN_FAILURE ;
@@ -1035,7 +1035,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
10351035 } else {
10361036 /* general case */
10371037 LASTMARK_SAVE ();
1038- if (state -> repeat )
1038+ if (state -> save_marks )
10391039 MARK_PUSH (ctx -> lastmark );
10401040
10411041 while ((Py_ssize_t )pattern [2 ] == SRE_MAXREPEAT
@@ -1044,12 +1044,12 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
10441044 DO_JUMP (JUMP_MIN_REPEAT_ONE ,jump_min_repeat_one ,
10451045 pattern + pattern [0 ]);
10461046 if (ret ) {
1047- if (state -> repeat )
1047+ if (state -> save_marks )
10481048 MARK_POP_DISCARD (ctx -> lastmark );
10491049 RETURN_ON_ERROR (ret );
10501050 RETURN_SUCCESS ;
10511051 }
1052- if (state -> repeat )
1052+ if (state -> save_marks )
10531053 MARK_POP_KEEP (ctx -> lastmark );
10541054 LASTMARK_RESTORE ();
10551055
@@ -1063,7 +1063,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
10631063 ptr ++ ;
10641064 ctx -> count ++ ;
10651065 }
1066- if (state -> repeat )
1066+ if (state -> save_marks )
10671067 MARK_POP_DISCARD (ctx -> lastmark );
10681068 }
10691069 RETURN_FAILURE ;
@@ -1140,10 +1140,12 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
11401140 ctx -> u .rep -> prev = state -> repeat ;
11411141 ctx -> u .rep -> last_ptr = NULL ;
11421142 state -> repeat = ctx -> u .rep ;
1143+ state -> save_marks ++ ;
11431144
11441145 state -> ptr = ptr ;
11451146 DO_JUMP (JUMP_REPEAT , jump_repeat , pattern + pattern [0 ]);
11461147 state -> repeat = ctx -> u .rep -> prev ;
1148+ state -> save_marks -- ;
11471149 repeat_pool_free (state , ctx -> u .rep );
11481150
11491151 if (ret ) {
@@ -1212,8 +1214,10 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
12121214 /* cannot match more repeated items here. make sure the
12131215 tail matches */
12141216 state -> repeat = ctx -> u .rep -> prev ;
1217+ state -> save_marks -- ;
12151218 DO_JUMP (JUMP_MAX_UNTIL_3 , jump_max_until_3 , pattern );
12161219 state -> repeat = ctx -> u .rep ; // restore repeat before return
1220+ state -> save_marks ++ ;
12171221
12181222 RETURN_ON_SUCCESS (ret );
12191223 state -> ptr = ptr ;
@@ -1250,22 +1254,26 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
12501254
12511255 /* see if the tail matches */
12521256 state -> repeat = ctx -> u .rep -> prev ;
1257+ state -> save_marks -- ;
12531258
12541259 LASTMARK_SAVE ();
1255- if (state -> repeat )
1260+ if (state -> save_marks )
12561261 MARK_PUSH (ctx -> lastmark );
12571262
12581263 DO_JUMP (JUMP_MIN_UNTIL_2 , jump_min_until_2 , pattern );
1259- SRE_REPEAT * repeat_of_tail = state -> repeat ;
1264+ /* save_marks is balanced across the jump, so this equals the
1265+ value tested for MARK_PUSH above */
1266+ int pushed = state -> save_marks != 0 ;
12601267 state -> repeat = ctx -> u .rep ; // restore repeat before return
1268+ state -> save_marks ++ ;
12611269
12621270 if (ret ) {
1263- if (repeat_of_tail )
1271+ if (pushed )
12641272 MARK_POP_DISCARD (ctx -> lastmark );
12651273 RETURN_ON_ERROR (ret );
12661274 RETURN_SUCCESS ;
12671275 }
1268- if (repeat_of_tail )
1276+ if (pushed )
12691277 MARK_POP (ctx -> lastmark );
12701278 LASTMARK_RESTORE ();
12711279
@@ -1302,16 +1310,10 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
13021310 pointer */
13031311 state -> ptr = ptr ;
13041312
1305- /* Set state->repeat to non-NULL */
1306- ctx -> u .rep = repeat_pool_malloc (state );
1307- if (!ctx -> u .rep ) {
1308- RETURN_ERROR (SRE_ERROR_MEMORY );
1309- }
1310- ctx -> u .rep -> count = -1 ;
1311- ctx -> u .rep -> pattern = NULL ;
1312- ctx -> u .rep -> prev = state -> repeat ;
1313- ctx -> u .rep -> last_ptr = NULL ;
1314- state -> repeat = ctx -> u .rep ;
1313+ /* Capture groups in the body can be revisited on backtracking
1314+ between iterations, so their marks must be saved and restored,
1315+ as is done inside a repeat. */
1316+ state -> save_marks ++ ;
13151317
13161318 /* Initialize Count to 0 */
13171319 ctx -> count = 0 ;
@@ -1327,9 +1329,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
13271329 }
13281330 else {
13291331 state -> ptr = ptr ;
1330- /* Restore state->repeat */
1331- state -> repeat = ctx -> u .rep -> prev ;
1332- repeat_pool_free (state , ctx -> u .rep );
1332+ state -> save_marks -- ;
13331333 RETURN_FAILURE ;
13341334 }
13351335 }
@@ -1402,9 +1402,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
14021402 }
14031403 }
14041404
1405- /* Restore state->repeat */
1406- state -> repeat = ctx -> u .rep -> prev ;
1407- repeat_pool_free (state , ctx -> u .rep );
1405+ state -> save_marks -- ;
14081406
14091407 /* Evaluate Tail */
14101408 /* Jump to end of pattern indicated by skip, and then skip
@@ -1586,17 +1584,17 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
15861584 if ((uintptr_t )(ptr - (SRE_CHAR * )state -> beginning ) >= pattern [1 ]) {
15871585 state -> ptr = ptr - pattern [1 ];
15881586 LASTMARK_SAVE ();
1589- if (state -> repeat )
1587+ if (state -> save_marks )
15901588 MARK_PUSH (ctx -> lastmark );
15911589
15921590 DO_JUMP0 (JUMP_ASSERT_NOT , jump_assert_not , pattern + 2 );
15931591 if (ret ) {
1594- if (state -> repeat )
1592+ if (state -> save_marks )
15951593 MARK_POP_DISCARD (ctx -> lastmark );
15961594 RETURN_ON_ERROR (ret );
15971595 RETURN_FAILURE ;
15981596 }
1599- if (state -> repeat )
1597+ if (state -> save_marks )
16001598 MARK_POP (ctx -> lastmark );
16011599 LASTMARK_RESTORE ();
16021600 }
0 commit comments