Skip to content

Commit

Permalink
gh-101955: Fix SystemError in possesive quantifier with alternative a…
Browse files Browse the repository at this point in the history
…nd group (GH-111362)

Co-authored-by: <[email protected]>
  • Loading branch information
serhiy-storchaka authored Nov 18, 2024
1 parent 7538e7f commit f9c5573
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Lib/test/test_re.py
Original file line number Diff line number Diff line change
Expand Up @@ -2640,6 +2640,12 @@ def test_bug_gh100061(self):
self.assertEqual(re.match("(?>(?:ab?c){1,3})", "aca").span(), (0, 2))
self.assertEqual(re.match("(?:ab?c){1,3}+", "aca").span(), (0, 2))

def test_bug_gh101955(self):
# Possessive quantifier with nested alternative with capture groups
self.assertEqual(re.match('((x)|y|z)*+', 'xyz').groups(), ('z', 'x'))
self.assertEqual(re.match('((x)|y|z){3}+', 'xyz').groups(), ('z', 'x'))
self.assertEqual(re.match('((x)|y|z){3,}+', 'xyz').groups(), ('z', 'x'))

@unittest.skipIf(multiprocessing is None, 'test requires multiprocessing')
def test_regression_gh94675(self):
pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix SystemError when match regular expression pattern containing some
combination of possessive quantifier, alternative and capture group.
18 changes: 18 additions & 0 deletions Modules/_sre/sre_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,17 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
pointer */
state->ptr = ptr;

/* Set state->repeat to non-NULL */
ctx->u.rep = repeat_pool_malloc(state);
if (!ctx->u.rep) {
RETURN_ERROR(SRE_ERROR_MEMORY);
}
ctx->u.rep->count = -1;
ctx->u.rep->pattern = NULL;
ctx->u.rep->prev = state->repeat;
ctx->u.rep->last_ptr = NULL;
state->repeat = ctx->u.rep;

/* Initialize Count to 0 */
ctx->count = 0;

Expand All @@ -1320,6 +1331,9 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
}
else {
state->ptr = ptr;
/* Restore state->repeat */
state->repeat = ctx->u.rep->prev;
repeat_pool_free(state, ctx->u.rep);
RETURN_FAILURE;
}
}
Expand Down Expand Up @@ -1392,6 +1406,10 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
}
}

/* Restore state->repeat */
state->repeat = ctx->u.rep->prev;
repeat_pool_free(state, ctx->u.rep);

/* Evaluate Tail */
/* Jump to end of pattern indicated by skip, and then skip
the SUCCESS op code that follows it. */
Expand Down

0 comments on commit f9c5573

Please sign in to comment.