aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-11-18 13:43:44 +0200
committerGitHub <noreply@github.com>2024-11-18 13:43:44 +0200
commitf9c5573dedcb2f2e9ae152672ce157987cdea612 (patch)
tree9c65e6d8d719e45951d2d55bd5da72f60c93fc8e
parent7538e7f5696408fa0aa02fce8a413a7dfac76a04 (diff)
downloadcpython-f9c5573dedcb2f2e9ae152672ce157987cdea612.tar.gz
cpython-f9c5573dedcb2f2e9ae152672ce157987cdea612.zip
gh-101955: Fix SystemError in possesive quantifier with alternative and group (GH-111362)
Co-authored-by: <wjssz@users.noreply.github.com>
-rw-r--r--Lib/test/test_re.py6
-rw-r--r--Misc/NEWS.d/next/Library/2023-10-26-16-36-22.gh-issue-101955.Ixu3IF.rst2
-rw-r--r--Modules/_sre/sre_lib.h18
3 files changed, 26 insertions, 0 deletions
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 1612fc7663e..0d3599be87f 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -2640,6 +2640,12 @@ class ReTests(unittest.TestCase):
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])*)*'
diff --git a/Misc/NEWS.d/next/Library/2023-10-26-16-36-22.gh-issue-101955.Ixu3IF.rst b/Misc/NEWS.d/next/Library/2023-10-26-16-36-22.gh-issue-101955.Ixu3IF.rst
new file mode 100644
index 00000000000..89431010f78
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-10-26-16-36-22.gh-issue-101955.Ixu3IF.rst
@@ -0,0 +1,2 @@
+Fix SystemError when match regular expression pattern containing some
+combination of possessive quantifier, alternative and capture group.
diff --git a/Modules/_sre/sre_lib.h b/Modules/_sre/sre_lib.h
index 0c93f512110..af4bfc56083 100644
--- a/Modules/_sre/sre_lib.h
+++ b/Modules/_sre/sre_lib.h
@@ -1306,6 +1306,17 @@ dispatch:
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;
@@ -1320,6 +1331,9 @@ dispatch:
}
else {
state->ptr = ptr;
+ /* Restore state->repeat */
+ state->repeat = ctx->u.rep->prev;
+ repeat_pool_free(state, ctx->u.rep);
RETURN_FAILURE;
}
}
@@ -1392,6 +1406,10 @@ dispatch:
}
}
+ /* 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. */