Skip to content

Commit 3068e45

Browse files
committed
Handle interaction of regexp's makesearch and MATCHALL more honestly.
Second thoughts about commit 824bf71: we apply makesearch() to an NFA after having determined whether it is a MATCHALL pattern. Prepending ".*" doesn't make it non-MATCHALL, but it does change the maximum possible match length, and makesearch() failed to update that. This has no ill effects given the stylized usage of search NFAs, but it seems like it's better to keep the data structure consistent. In particular, fixing this allows more honest handling of the MATCHALL check in matchuntil(): we can now assert that maxmatchall is infinity, instead of lamely assuming that it should act that way. In passing, improve the code in dump[c]nfa so that infinite maxmatchall is printed as "inf" not a magic number.
1 parent ba05dfe commit 3068e45

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

src/backend/regex/regc_nfa.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,8 +3602,13 @@ dumpnfa(struct nfa *nfa,
36023602
if (nfa->flags & HASLACONS)
36033603
fprintf(f, ", haslacons");
36043604
if (nfa->flags & MATCHALL)
3605-
fprintf(f, ", minmatchall %d, maxmatchall %d",
3606-
nfa->minmatchall, nfa->maxmatchall);
3605+
{
3606+
fprintf(f, ", minmatchall %d", nfa->minmatchall);
3607+
if (nfa->maxmatchall == DUPINF)
3608+
fprintf(f, ", maxmatchall inf");
3609+
else
3610+
fprintf(f, ", maxmatchall %d", nfa->maxmatchall);
3611+
}
36073612
fprintf(f, "\n");
36083613
for (s = nfa->states; s != NULL; s = s->next)
36093614
{
@@ -3766,8 +3771,13 @@ dumpcnfa(struct cnfa *cnfa,
37663771
if (cnfa->flags & HASLACONS)
37673772
fprintf(f, ", haslacons");
37683773
if (cnfa->flags & MATCHALL)
3769-
fprintf(f, ", minmatchall %d, maxmatchall %d",
3770-
cnfa->minmatchall, cnfa->maxmatchall);
3774+
{
3775+
fprintf(f, ", minmatchall %d", cnfa->minmatchall);
3776+
if (cnfa->maxmatchall == DUPINF)
3777+
fprintf(f, ", maxmatchall inf");
3778+
else
3779+
fprintf(f, ", maxmatchall %d", cnfa->maxmatchall);
3780+
}
37713781
fprintf(f, "\n");
37723782
for (st = 0; st < cnfa->nstates; st++)
37733783
dumpcstate(st, cnfa, f);

src/backend/regex/regcomp.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,13 @@ makesearch(struct vars *v,
598598
/* and ^* and \A* too -- not always necessary, but harmless */
599599
newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
600600
newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
601+
602+
/*
603+
* The pattern is still MATCHALL if it was before, but the max match
604+
* length is now infinity.
605+
*/
606+
if (nfa->flags & MATCHALL)
607+
nfa->maxmatchall = DUPINF;
601608
}
602609

603610
/*

src/backend/regex/rege_dfa.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -385,14 +385,10 @@ matchuntil(struct vars *v,
385385
{
386386
size_t nchr = probe - v->start;
387387

388-
/*
389-
* It might seem that we should check maxmatchall too, but the .* at
390-
* the front of the pattern absorbs any extra characters (and it was
391-
* tacked on *after* computing minmatchall/maxmatchall). Thus, we
392-
* should match if there are at least minmatchall characters.
393-
*/
394388
if (nchr < d->cnfa->minmatchall)
395389
return 0;
390+
/* maxmatchall will always be infinity, cf. makesearch() */
391+
assert(d->cnfa->maxmatchall == DUPINF);
396392
return 1;
397393
}
398394

0 commit comments

Comments
 (0)