]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-101955: Fix SystemError in possesive quantifier with alternative and group (GH...
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 18 Nov 2024 11:43:44 +0000 (13:43 +0200)
committerGitHub <noreply@github.com>
Mon, 18 Nov 2024 11:43:44 +0000 (13:43 +0200)
Co-authored-by: <wjssz@users.noreply.github.com>
Lib/test/test_re.py
Misc/NEWS.d/next/Library/2023-10-26-16-36-22.gh-issue-101955.Ixu3IF.rst [new file with mode: 0644]
Modules/_sre/sre_lib.h

index 1612fc7663e87e4d7366e6abc5828a6b224886f0..0d3599be87f2283071e136170cedb1f76b79679f 100644 (file)
@@ -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 (file)
index 0000000..8943101
--- /dev/null
@@ -0,0 +1,2 @@
+Fix SystemError when match regular expression pattern containing some
+combination of possessive quantifier, alternative and capture group.
index 0c93f5121103e8175c4256c237cebea544ea5030..af4bfc56083bcba407188b664310c0ddc439100c 100644 (file)
@@ -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. */