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],
}
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;
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;
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));
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 */
(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;
}
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;
}
/* 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;