From 5337d33cc6e46a6eb281f2abb325b29c882a82b2 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sat, 27 Jun 2026 21:07:50 +0200 Subject: fixup REG_ANCHORED: the checks have to be in shortest() I put them into longest() as well, but it appears that both find() and cfind() will always try shortest() first and should abort if that returns NULL. --- rege_dfa.c | 12 ++++++++++++ regexec.c | 6 ------ regtest_terex.sh | 6 ++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/rege_dfa.c b/rege_dfa.c index 9764c33..a9686b1 100644 --- a/rege_dfa.c +++ b/rege_dfa.c @@ -97,6 +97,9 @@ longest( break; /* NOTE BREAK OUT */ } } + if (ss->flags & NOPROGRESS && v->eflags & REG_ANCHORED) { + return NULL; + } cp = nextchr(v, cp); ss->lastseen = cp; css = ss; @@ -112,6 +115,9 @@ longest( break; /* NOTE BREAK OUT */ } } + if (ss->flags & NOPROGRESS && v->eflags & REG_ANCHORED) { + return NULL; + } cp = nextchr(v, cp); ss->lastseen = cp; css = ss; @@ -230,6 +236,9 @@ shortest( break; /* NOTE BREAK OUT */ } } + if (ss->flags & NOPROGRESS && v->eflags & REG_ANCHORED) { + return NULL; + } cp = nextchr(v, cp); ss->lastseen = cp; css = ss; @@ -248,6 +257,9 @@ shortest( break; /* NOTE BREAK OUT */ } } + if (ss->flags & NOPROGRESS && v->eflags & REG_ANCHORED) { + return NULL; + } cp = nextchr(v, cp); ss->lastseen = cp; css = ss; diff --git a/regexec.c b/regexec.c index 848d911..d047929 100644 --- a/regexec.c +++ b/regexec.c @@ -415,9 +415,6 @@ find( if (end != NULL) { break; /* NOTE BREAK OUT */ } - if (v->eflags & REG_ANCHORED) { - break; /* NOTE BREAK OUT */ - } } assert(end != NULL); /* search RE succeeded so loop should */ freedfa(d); @@ -581,9 +578,6 @@ cfindloop( estop = prevchr(v, end); } } - if (v->eflags & REG_ANCHORED) { - break; /* NOTE BREAK OUT */ - } } } while (close < v->stop); diff --git a/regtest_terex.sh b/regtest_terex.sh index 930867d..0f903d3 100755 --- a/regtest_terex.sh +++ b/regtest_terex.sh @@ -107,8 +107,9 @@ cat<<-EOF>$rgsrc //memset(&cre, '\0', sizeof(cre)); - while ((ch = getopt(argc, argv, "raA")) != -1) { + while ((ch = getopt(argc, argv, "iraA")) != -1) { switch (ch) { + case 'i': cflags |= REG_ICASE; break; case 'r': cflags |= REG_RAW; break; case 'a': cflags |= REG_BOSONLY; break; case 'A': eflags |= REG_ANCHORED; break; @@ -363,7 +364,8 @@ test "$resp" = "абвгд" && f_ok "$msg" || f_no "$msg" "$resp" #----------------------------------- resp=`$rgbin -A 0 'ABC' 'blablaABC' 2>&1` msg="Anchored search (failure)" -test -z "$resp" && f_ok "$msg" || f_no "$msg" "$resp" +if echo "$resp"|grep "failed to match">/dev/null; +then f_ok "$msg"; else f_no "$msg" "$resp"; fi resp=`$rgbin -A 1 '(ABC)' 'ABCblablaABC' 2>&1` msg="Anchored search (success)" test "$resp" = "ABC" && f_ok "$msg" || f_no "$msg" "$resp" -- cgit v1.2.3