Skip to content

Commit f9c5573

Browse files
gh-101955: Fix SystemError in possesive quantifier with alternative and group (GH-111362)
Co-authored-by: <wjssz@users.noreply.github.com>
1 parent 7538e7f commit f9c5573

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

Diff for: Lib/test/test_re.py

+6
Original file line numberDiff line numberDiff line change
@@ -2640,6 +2640,12 @@ def test_bug_gh100061(self):
26402640
self.assertEqual(re.match("(?>(?:ab?c){1,3})", "aca").span(), (0, 2))
26412641
self.assertEqual(re.match("(?:ab?c){1,3}+", "aca").span(), (0, 2))
26422642

2643+
def test_bug_gh101955(self):
2644+
# Possessive quantifier with nested alternative with capture groups
2645+
self.assertEqual(re.match('((x)|y|z)*+', 'xyz').groups(), ('z', 'x'))
2646+
self.assertEqual(re.match('((x)|y|z){3}+', 'xyz').groups(), ('z', 'x'))
2647+
self.assertEqual(re.match('((x)|y|z){3,}+', 'xyz').groups(), ('z', 'x'))
2648+
26432649
@unittest.skipIf(multiprocessing is None, 'test requires multiprocessing')
26442650
def test_regression_gh94675(self):
26452651
pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix SystemError when match regular expression pattern containing some
2+
combination of possessive quantifier, alternative and capture group.

Diff for: Modules/_sre/sre_lib.h

+18
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,17 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
13061306
pointer */
13071307
state->ptr = ptr;
13081308

1309+
/* Set state->repeat to non-NULL */
1310+
ctx->u.rep = repeat_pool_malloc(state);
1311+
if (!ctx->u.rep) {
1312+
RETURN_ERROR(SRE_ERROR_MEMORY);
1313+
}
1314+
ctx->u.rep->count = -1;
1315+
ctx->u.rep->pattern = NULL;
1316+
ctx->u.rep->prev = state->repeat;
1317+
ctx->u.rep->last_ptr = NULL;
1318+
state->repeat = ctx->u.rep;
1319+
13091320
/* Initialize Count to 0 */
13101321
ctx->count = 0;
13111322

@@ -1320,6 +1331,9 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
13201331
}
13211332
else {
13221333
state->ptr = ptr;
1334+
/* Restore state->repeat */
1335+
state->repeat = ctx->u.rep->prev;
1336+
repeat_pool_free(state, ctx->u.rep);
13231337
RETURN_FAILURE;
13241338
}
13251339
}
@@ -1392,6 +1406,10 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
13921406
}
13931407
}
13941408

1409+
/* Restore state->repeat */
1410+
state->repeat = ctx->u.rep->prev;
1411+
repeat_pool_free(state, ctx->u.rep);
1412+
13951413
/* Evaluate Tail */
13961414
/* Jump to end of pattern indicated by skip, and then skip
13971415
the SUCCESS op code that follows it. */

0 commit comments

Comments
 (0)