summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorGustavo Niemeyer <gustavo@niemeyer.net>2003-04-27 13:25:21 (GMT)
committerGustavo Niemeyer <gustavo@niemeyer.net>2003-04-27 13:25:21 (GMT)
commit3646ab98af41f37eacf9cdc9d711327956b911f0 (patch)
tree5e411ea69c62645ccfa7be2af992764c886e3932 /Modules
parentc34f2555bd414254f941d0659ba9c229b96ec728 (diff)
downloadcpython-3646ab98af41f37eacf9cdc9d711327956b911f0.zip
cpython-3646ab98af41f37eacf9cdc9d711327956b911f0.tar.gz
cpython-3646ab98af41f37eacf9cdc9d711327956b911f0.tar.bz2
Fix for part of the problem mentioned in #725149 by Greg Chapman.
This problem is related to a wrong behavior from mark_save/restore(), which don't restore the mark_stack_base before restoring the marks. Greg's suggestion was to change the asserts, which happen to be the only recursive ops that can continue the loop, but the problem would happen to any operation with the same behavior. So, rather than hardcoding this into asserts, I have changed mark_save/restore() to always restore the stackbase before restoring the marks. Both solutions should fix these two cases, presented by Greg: >>> re.match('(a)(?:(?=(b)*)c)*', 'abb').groups() ('b', None) >>> re.match('(a)((?!(b)*))*', 'abb').groups() ('b', None, None) The rest of the bug and patch in #725149 must be discussed further.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_sre.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/Modules/_sre.c b/Modules/_sre.c
index b9e1827..4f040f1 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -279,7 +279,7 @@ mark_fini(SRE_STATE* state)
}
static int
-mark_save(SRE_STATE* state, int lo, int hi)
+mark_save(SRE_STATE* state, int lo, int hi, int *mark_stack_base)
{
void* stack;
int size;
@@ -323,11 +323,13 @@ mark_save(SRE_STATE* state, int lo, int hi)
state->mark_stack_base += size;
+ *mark_stack_base = state->mark_stack_base;
+
return 0;
}
static int
-mark_restore(SRE_STATE* state, int lo, int hi)
+mark_restore(SRE_STATE* state, int lo, int hi, int *mark_stack_base)
{
int size;
@@ -336,7 +338,7 @@ mark_restore(SRE_STATE* state, int lo, int hi)
size = (hi - lo) + 1;
- state->mark_stack_base -= size;
+ state->mark_stack_base = *mark_stack_base - size;
TRACE(("copy %d:%d from %d\n", lo, hi, state->mark_stack_base));
@@ -712,7 +714,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
SRE_CHAR* ptr = state->ptr;
int i, count;
SRE_REPEAT* rp;
- int lastmark, lastindex;
+ int lastmark, lastindex, mark_stack_base;
SRE_CODE chr;
SRE_REPEAT rep; /* FIXME: <fl> allocate in STATE instead */
@@ -948,7 +950,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
(ptr >= end || !SRE_CHARSET(pattern + 3, (SRE_CODE) *ptr)))
continue;
if (state->repeat) {
- i = mark_save(state, 0, lastmark);
+ i = mark_save(state, 0, lastmark, &mark_stack_base);
if (i < 0)
return i;
}
@@ -957,7 +959,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
if (i)
return i;
if (state->repeat) {
- i = mark_restore(state, 0, lastmark);
+ i = mark_restore(state, 0, lastmark, &mark_stack_base);
if (i < 0)
return i;
}
@@ -1157,14 +1159,14 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
/* we may have enough matches, but if we can
match another item, do so */
rp->count = count;
- i = mark_save(state, 0, lastmark);
+ i = mark_save(state, 0, lastmark, &mark_stack_base);
if (i < 0)
return i;
/* RECURSIVE */
i = SRE_MATCH(state, rp->pattern + 3, level + 1);
if (i)
return i;
- i = mark_restore(state, 0, lastmark);
+ i = mark_restore(state, 0, lastmark, &mark_stack_base);
LASTMARK_RESTORE();
if (i < 0)
return i;