Skip to content

Commit 190c798

Browse files
committed
Simplify memory management for regex DFAs a little.
Coverity complained that functions in regexec.c might leak DFA storage. It's wrong, but this logic is confusing enough that it's not so surprising Coverity couldn't make sense of it. Rewrite in hopes of making it more legible to humans as well as machines.
1 parent 6ee479a commit 190c798

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

src/backend/regex/rege_dfa.c

+10-8
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ newdfa(struct vars *v,
499499
struct dfa *d;
500500
size_t nss = cnfa->nstates * 2;
501501
int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
502-
struct smalldfa *smallwas = sml;
502+
bool ismalloced = false;
503503

504504
assert(cnfa != NULL && cnfa->nstates != 0);
505505

@@ -514,15 +514,16 @@ newdfa(struct vars *v,
514514
ERR(REG_ESPACE);
515515
return NULL;
516516
}
517+
ismalloced = true;
517518
}
518519
d = &sml->dfa;
519520
d->ssets = sml->ssets;
520521
d->statesarea = sml->statesarea;
521522
d->work = &d->statesarea[nss];
522523
d->outsarea = sml->outsarea;
523524
d->incarea = sml->incarea;
524-
d->cptsmalloced = 0;
525-
d->mallocarea = (smallwas == NULL) ? (char *) sml : NULL;
525+
d->ismalloced = ismalloced;
526+
d->arraysmalloced = false; /* not separately allocated, anyway */
526527
}
527528
else
528529
{
@@ -540,8 +541,9 @@ newdfa(struct vars *v,
540541
sizeof(struct sset *));
541542
d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors *
542543
sizeof(struct arcp));
543-
d->cptsmalloced = 1;
544-
d->mallocarea = (char *) d;
544+
d->ismalloced = true;
545+
d->arraysmalloced = true;
546+
/* now freedfa() will behave sanely */
545547
if (d->ssets == NULL || d->statesarea == NULL ||
546548
d->outsarea == NULL || d->incarea == NULL)
547549
{
@@ -573,7 +575,7 @@ newdfa(struct vars *v,
573575
static void
574576
freedfa(struct dfa *d)
575577
{
576-
if (d->cptsmalloced)
578+
if (d->arraysmalloced)
577579
{
578580
if (d->ssets != NULL)
579581
FREE(d->ssets);
@@ -585,8 +587,8 @@ freedfa(struct dfa *d)
585587
FREE(d->incarea);
586588
}
587589

588-
if (d->mallocarea != NULL)
589-
FREE(d->mallocarea);
590+
if (d->ismalloced)
591+
FREE(d);
590592
}
591593

592594
/*

src/backend/regex/regexec.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ struct dfa
7777
chr *lastpost; /* location of last cache-flushed success */
7878
chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
7979
struct sset *search; /* replacement-search-pointer memory */
80-
int cptsmalloced; /* were the areas individually malloced? */
81-
char *mallocarea; /* self, or master malloced area, or NULL */
80+
bool ismalloced; /* should this struct dfa be freed? */
81+
bool arraysmalloced; /* should its subsidiary arrays be freed? */
8282
};
8383

8484
#define WORK 1 /* number of work bitvectors needed */
@@ -88,7 +88,7 @@ struct dfa
8888
#define FEWCOLORS 15
8989
struct smalldfa
9090
{
91-
struct dfa dfa;
91+
struct dfa dfa; /* must be first */
9292
struct sset ssets[FEWSTATES * 2];
9393
unsigned statesarea[FEWSTATES * 2 + WORK];
9494
struct sset *outsarea[FEWSTATES * 2 * FEWCOLORS];

0 commit comments

Comments
 (0)