Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit caf1c9d

Browse files
committed
- Included detailed documentation in _sre.c explaining how, when, and why
to use LASTMARK_SAVE()/LASTMARK_RESTORE(), based on the discussion in patch #712900. - Cleaned up LASTMARK_SAVE()/LASTMARK_RESTORE() usage, based on the established rules. - Moved the upper part of the just commited patch (relative to bug #725106) to outside the for() loop of BRANCH OP. There's no need to mark_save() in every loop iteration.
1 parent 3646ab9 commit caf1c9d

1 file changed

Lines changed: 41 additions & 17 deletions

File tree

Modules/_sre.c

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,34 @@ SRE_INFO(SRE_STATE* state, SRE_CODE* pattern)
688688
}
689689
#endif
690690

691-
/* macros to preserve lastmark in case of backtracking */
691+
/* The macros below should be used to protect recursive SRE_MATCH()
692+
* calls that *failed* and do *not* return immediately (IOW, those
693+
* that will backtrack). Explaining:
694+
*
695+
* - Recursive SRE_MATCH() returned true: that's usually a success
696+
* (besides atypical cases like ASSERT_NOT), therefore there's no
697+
* reason to restore lastmark;
698+
*
699+
* - Recursive SRE_MATCH() returned false but the current SRE_MATCH()
700+
* is returning to the caller: If the current SRE_MATCH() is the
701+
* top function of the recursion, returning false will be a matching
702+
* failure, and it doesn't matter where lastmark is pointing to.
703+
* If it's *not* the top function, it will be a recursive SRE_MATCH()
704+
* failure by itself, and the calling SRE_MATCH() will have to deal
705+
* with the failure by the same rules explained here (it will restore
706+
* lastmark by itself if necessary);
707+
*
708+
* - Recursive SRE_MATCH() returned false, and will continue the
709+
* outside 'for' loop: must be protected when breaking, since the next
710+
* OP could potentially depend on lastmark;
711+
*
712+
* - Recursive SRE_MATCH() returned false, and will be called again
713+
* inside a local for/while loop: must be protected between each
714+
* loop iteration, since the recursive SRE_MATCH() could do anything,
715+
* and could potentially depend on lastmark.
716+
*
717+
* For more information, check the discussion at SF patch #712900.
718+
*/
692719
#define LASTMARK_SAVE() \
693720
do { \
694721
lastmark = state->lastmark; \
@@ -942,18 +969,18 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
942969
/* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
943970
TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
944971
LASTMARK_SAVE();
972+
if (state->repeat) {
973+
i = mark_save(state, 0, lastmark, &mark_stack_base);
974+
if (i < 0)
975+
return i;
976+
}
945977
for (; pattern[0]; pattern += pattern[0]) {
946978
if (pattern[1] == SRE_OP_LITERAL &&
947979
(ptr >= end || (SRE_CODE) *ptr != pattern[2]))
948980
continue;
949981
if (pattern[1] == SRE_OP_IN &&
950982
(ptr >= end || !SRE_CHARSET(pattern + 3, (SRE_CODE) *ptr)))
951983
continue;
952-
if (state->repeat) {
953-
i = mark_save(state, 0, lastmark, &mark_stack_base);
954-
if (i < 0)
955-
return i;
956-
}
957984
state->ptr = ptr;
958985
i = SRE_MATCH(state, pattern + 1, level + 1);
959986
if (i)
@@ -1092,12 +1119,12 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
10921119
c = SRE_COUNT(state, pattern+3, 1, level+1);
10931120
if (c < 0)
10941121
return c;
1095-
LASTMARK_RESTORE();
10961122
if (c == 0)
10971123
break;
10981124
assert(c == 1);
10991125
ptr++;
11001126
count++;
1127+
LASTMARK_RESTORE();
11011128
}
11021129
}
11031130
return 0;
@@ -1140,8 +1167,6 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
11401167

11411168
TRACE(("|%p|%p|MAX_UNTIL %d\n", pattern, ptr, count));
11421169

1143-
LASTMARK_SAVE();
1144-
11451170
if (count < rp->pattern[1]) {
11461171
/* not enough matches */
11471172
rp->count = count;
@@ -1151,14 +1176,14 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
11511176
return i;
11521177
rp->count = count - 1;
11531178
state->ptr = ptr;
1154-
LASTMARK_RESTORE();
11551179
return 0;
11561180
}
11571181

11581182
if (count < rp->pattern[2] || rp->pattern[2] == 65535) {
11591183
/* we may have enough matches, but if we can
11601184
match another item, do so */
11611185
rp->count = count;
1186+
LASTMARK_SAVE();
11621187
i = mark_save(state, 0, lastmark, &mark_stack_base);
11631188
if (i < 0)
11641189
return i;
@@ -1167,9 +1192,9 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
11671192
if (i)
11681193
return i;
11691194
i = mark_restore(state, 0, lastmark, &mark_stack_base);
1170-
LASTMARK_RESTORE();
11711195
if (i < 0)
11721196
return i;
1197+
LASTMARK_RESTORE();
11731198
rp->count = count - 1;
11741199
state->ptr = ptr;
11751200
}
@@ -1182,7 +1207,6 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
11821207
return i;
11831208
state->repeat = rp;
11841209
state->ptr = ptr;
1185-
LASTMARK_RESTORE();
11861210
return 0;
11871211

11881212
case SRE_OP_MIN_UNTIL:
@@ -1200,8 +1224,6 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
12001224
TRACE(("|%p|%p|MIN_UNTIL %d %p\n", pattern, ptr, count,
12011225
rp->pattern));
12021226

1203-
LASTMARK_SAVE();
1204-
12051227
if (count < rp->pattern[1]) {
12061228
/* not enough matches */
12071229
rp->count = count;
@@ -1211,10 +1233,11 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
12111233
return i;
12121234
rp->count = count-1;
12131235
state->ptr = ptr;
1214-
LASTMARK_RESTORE();
12151236
return 0;
12161237
}
12171238

1239+
LASTMARK_SAVE();
1240+
12181241
/* see if the tail matches */
12191242
state->repeat = rp->prev;
12201243
i = SRE_MATCH(state, pattern, level + 1);
@@ -1224,18 +1247,19 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
12241247
state->ptr = ptr;
12251248
state->repeat = rp;
12261249

1227-
LASTMARK_RESTORE();
12281250
if (count >= rp->pattern[2] && rp->pattern[2] != 65535)
12291251
return 0;
12301252

1253+
LASTMARK_RESTORE();
1254+
12311255
rp->count = count;
12321256
/* RECURSIVE */
12331257
i = SRE_MATCH(state, rp->pattern + 3, level + 1);
12341258
if (i)
12351259
return i;
12361260
rp->count = count - 1;
12371261
state->ptr = ptr;
1238-
LASTMARK_RESTORE();
1262+
12391263
return 0;
12401264

12411265
default:

0 commit comments

Comments
 (0)