Skip to content

Commit 06dc4bd

Browse files
[3.12] gh-101955: Fix SystemError in possesive quantifier with alternative and group (GH-111362) (GH-126963)
(cherry picked from commit f9c5573) Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 8eb25fa commit 06dc4bd

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

Lib/test/test_re.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,12 @@ def test_bug_gh106052(self):
26012601
self.assertEqual(re.match("(?>(?:ab?c){1,3})", "aca").span(), (0, 2))
26022602
self.assertEqual(re.match("(?:ab?c){1,3}+", "aca").span(), (0, 2))
26032603

2604+
def test_bug_gh101955(self):
2605+
# Possessive quantifier with nested alternative with capture groups
2606+
self.assertEqual(re.match('((x)|y|z)*+', 'xyz').groups(), ('z', 'x'))
2607+
self.assertEqual(re.match('((x)|y|z){3}+', 'xyz').groups(), ('z', 'x'))
2608+
self.assertEqual(re.match('((x)|y|z){3,}+', 'xyz').groups(), ('z', 'x'))
2609+
26042610
@unittest.skipIf(multiprocessing is None, 'test requires multiprocessing')
26052611
def test_regression_gh94675(self):
26062612
pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*'
Lines changed: 2 additions & 0 deletions
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.

Modules/_sre/sre_lib.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,17 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
12691269
pointer */
12701270
state->ptr = ptr;
12711271

1272+
/* Set state->repeat to non-NULL */
1273+
ctx->u.rep = repeat_pool_malloc(state);
1274+
if (!ctx->u.rep) {
1275+
RETURN_ERROR(SRE_ERROR_MEMORY);
1276+
}
1277+
ctx->u.rep->count = -1;
1278+
ctx->u.rep->pattern = NULL;
1279+
ctx->u.rep->prev = state->repeat;
1280+
ctx->u.rep->last_ptr = NULL;
1281+
state->repeat = ctx->u.rep;
1282+
12721283
/* Initialize Count to 0 */
12731284
ctx->count = 0;
12741285

@@ -1283,6 +1294,9 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
12831294
}
12841295
else {
12851296
state->ptr = ptr;
1297+
/* Restore state->repeat */
1298+
state->repeat = ctx->u.rep->prev;
1299+
repeat_pool_free(state, ctx->u.rep);
12861300
RETURN_FAILURE;
12871301
}
12881302
}
@@ -1355,6 +1369,10 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
13551369
}
13561370
}
13571371

1372+
/* Restore state->repeat */
1373+
state->repeat = ctx->u.rep->prev;
1374+
repeat_pool_free(state, ctx->u.rep);
1375+
13581376
/* Evaluate Tail */
13591377
/* Jump to end of pattern indicated by skip, and then skip
13601378
the SUCCESS op code that follows it. */

0 commit comments

Comments
 (0)