Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8f72bec

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 d782d59 commit 8f72bec

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

src/backend/regex/regc_nfa.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -3660,8 +3660,13 @@ dumpnfa(struct nfa *nfa,
36603660
if (nfa->flags & HASLACONS)
36613661
fprintf(f, ", haslacons");
36623662
if (nfa->flags & MATCHALL)
3663-
fprintf(f, ", minmatchall %d, maxmatchall %d",
3664-
nfa->minmatchall, nfa->maxmatchall);
3663+
{
3664+
fprintf(f, ", minmatchall %d", nfa->minmatchall);
3665+
if (nfa->maxmatchall == DUPINF)
3666+
fprintf(f, ", maxmatchall inf");
3667+
else
3668+
fprintf(f, ", maxmatchall %d", nfa->maxmatchall);
3669+
}
36653670
fprintf(f, "\n");
36663671
for (s = nfa->states; s != NULL; s = s->next)
36673672
{
@@ -3824,8 +3829,13 @@ dumpcnfa(struct cnfa *cnfa,
38243829
if (cnfa->flags & HASLACONS)
38253830
fprintf(f, ", haslacons");
38263831
if (cnfa->flags & MATCHALL)
3827-
fprintf(f, ", minmatchall %d, maxmatchall %d",
3828-
cnfa->minmatchall, cnfa->maxmatchall);
3832+
{
3833+
fprintf(f, ", minmatchall %d", cnfa->minmatchall);
3834+
if (cnfa->maxmatchall == DUPINF)
3835+
fprintf(f, ", maxmatchall inf");
3836+
else
3837+
fprintf(f, ", maxmatchall %d", cnfa->maxmatchall);
3838+
}
38293839
fprintf(f, "\n");
38303840
for (st = 0; st < cnfa->nstates; st++)
38313841
dumpcstate(st, cnfa, f);

src/backend/regex/regcomp.c

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

604611
/*

src/backend/regex/rege_dfa.c

+2-6
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)