summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_re.py7
-rw-r--r--Modules/_sre.c18
2 files changed, 17 insertions, 8 deletions
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 7ba9a1b..6eebedf 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -295,6 +295,13 @@ class ReTests(unittest.TestCase):
self.assertEqual(re.match('^((a)c|[ab])*?c', 'abc').groups(),
('b', None))
+ def test_bug_725149(self):
+ # mark_stack_base restoring before restoring marks
+ self.assertEqual(re.match('(a)(?:(?=(b)*)c)*', 'abb').groups(),
+ ('a', None))
+ self.assertEqual(re.match('(a)((?!(b)*))*', 'abb').groups(),
+ ('a', None, None))
+
def test_finditer(self):
iter = re.finditer(r":+", "a:b::c:::d")
self.assertEqual([item.group(0) for item in iter],
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;