bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] regex: fix backreference matching


From: Egor Ignatov
Subject: [PATCH] regex: fix backreference matching
Date: Wed, 16 Jun 2021 12:46:15 +0300

This fixes a bug described in 70b673eb7.

* lib/regexec.c (set_regs): Revert pop condition changed in the
commit mentioned above.
(proceed_next_node): Always proceed on OP_BACK_REF to the
next node if naccepted is 0.
(update_regs): Fix optional sub expression boundaries matching.
* tests/test-regex.c: Fix tests.

Signed-off-by: Egor Ignatov <egori@altlinux.org>
---
 lib/regexec.c      | 12 ++++++------
 tests/test-regex.c |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/regexec.c b/lib/regexec.c
index 5d4113c9d..23b984a21 100644
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -1292,9 +1292,9 @@ proceed_next_node (const re_match_context_t *mctx, Idx 
nregs, regmatch_t *regs,
              if (__glibc_unlikely (! ok))
                return -2;
              dest_node = dfa->edests[node].elems[0];
-             if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
-                                       dest_node))
-               return dest_node;
+             if(dfa->nodes[dest_node].type == END_OF_RE)
+               regs[0].rm_eo = *pidx;
+             return dest_node;
            }
        }
 
@@ -1413,8 +1413,7 @@ set_regs (const regex_t *preg, const re_match_context_t 
*mctx, size_t nmatch,
     {
       update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
 
-      if ((idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
-         || (fs && re_node_set_contains (&eps_via_nodes, cur_node)))
+      if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
        {
          Idx reg_idx;
          cur_node = -1;
@@ -1514,7 +1513,8 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
          else
            {
              if (dfa->nodes[cur_node].opt_subexp
-                 && prev_idx_match[reg_num].rm_so != -1)
+                 && prev_idx_match[reg_num].rm_so != -1
+                 && pmatch[reg_num].rm_eo != -1)
                /* We transited through an empty match for an optional
                   subexpression, like (a?)*, and this is not the subexp's
                   first match.  Copy back the old content of the registers
diff --git a/tests/test-regex.c b/tests/test-regex.c
index 7ea73cfb6..f73909258 100644
--- a/tests/test-regex.c
+++ b/tests/test-regex.c
@@ -119,7 +119,7 @@ static struct
   /* Test for *+ match.  */
   { "^a*+(.)", "ab", REG_EXTENDED, 2, { { 0, 2 }, { 1, 2 } } },
   /* Test for ** match.  */
-  { "^(a*)*(.)", "ab", REG_EXTENDED, 3, { { 0, 2 }, { 0, 1 }, { 1, 2 } } },
+  { "^(a*)*(.)", "ab", REG_EXTENDED, 3, { { 0, 2 }, { 1, 1 }, { 1, 2 } } },
 };
 
 static void
@@ -431,7 +431,7 @@ main (void)
       else if (! (regs.start[0] == 0 && regs.end[0] == 1))
         report_error ("re_search '%s' on '%s' returned wrong match [%d,%d)",
                       pat_sub2, data, (int) regs.start[0], (int) regs.end[0]);
-      else if (! (regs.start[1] == 0 && regs.end[1] == 0))
+      else if (! (regs.start[1] == 1 && regs.end[1] == 1))
         report_error ("re_search '%s' on '%s' returned wrong submatch [%d,%d)",
                       pat_sub2, data, regs.start[1], regs.end[1]);
       regfree (&regex);
-- 
2.29.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]