mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 23:01:35 +02:00
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.
This commit is contained in:
parent
6ee479abfc
commit
190c79884a
@ -499,7 +499,7 @@ newdfa(struct vars *v,
|
|||||||
struct dfa *d;
|
struct dfa *d;
|
||||||
size_t nss = cnfa->nstates * 2;
|
size_t nss = cnfa->nstates * 2;
|
||||||
int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
|
int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
|
||||||
struct smalldfa *smallwas = sml;
|
bool ismalloced = false;
|
||||||
|
|
||||||
assert(cnfa != NULL && cnfa->nstates != 0);
|
assert(cnfa != NULL && cnfa->nstates != 0);
|
||||||
|
|
||||||
@ -514,6 +514,7 @@ newdfa(struct vars *v,
|
|||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
ismalloced = true;
|
||||||
}
|
}
|
||||||
d = &sml->dfa;
|
d = &sml->dfa;
|
||||||
d->ssets = sml->ssets;
|
d->ssets = sml->ssets;
|
||||||
@ -521,8 +522,8 @@ newdfa(struct vars *v,
|
|||||||
d->work = &d->statesarea[nss];
|
d->work = &d->statesarea[nss];
|
||||||
d->outsarea = sml->outsarea;
|
d->outsarea = sml->outsarea;
|
||||||
d->incarea = sml->incarea;
|
d->incarea = sml->incarea;
|
||||||
d->cptsmalloced = 0;
|
d->ismalloced = ismalloced;
|
||||||
d->mallocarea = (smallwas == NULL) ? (char *) sml : NULL;
|
d->arraysmalloced = false; /* not separately allocated, anyway */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -540,8 +541,9 @@ newdfa(struct vars *v,
|
|||||||
sizeof(struct sset *));
|
sizeof(struct sset *));
|
||||||
d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors *
|
d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors *
|
||||||
sizeof(struct arcp));
|
sizeof(struct arcp));
|
||||||
d->cptsmalloced = 1;
|
d->ismalloced = true;
|
||||||
d->mallocarea = (char *) d;
|
d->arraysmalloced = true;
|
||||||
|
/* now freedfa() will behave sanely */
|
||||||
if (d->ssets == NULL || d->statesarea == NULL ||
|
if (d->ssets == NULL || d->statesarea == NULL ||
|
||||||
d->outsarea == NULL || d->incarea == NULL)
|
d->outsarea == NULL || d->incarea == NULL)
|
||||||
{
|
{
|
||||||
@ -573,7 +575,7 @@ newdfa(struct vars *v,
|
|||||||
static void
|
static void
|
||||||
freedfa(struct dfa *d)
|
freedfa(struct dfa *d)
|
||||||
{
|
{
|
||||||
if (d->cptsmalloced)
|
if (d->arraysmalloced)
|
||||||
{
|
{
|
||||||
if (d->ssets != NULL)
|
if (d->ssets != NULL)
|
||||||
FREE(d->ssets);
|
FREE(d->ssets);
|
||||||
@ -585,8 +587,8 @@ freedfa(struct dfa *d)
|
|||||||
FREE(d->incarea);
|
FREE(d->incarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->mallocarea != NULL)
|
if (d->ismalloced)
|
||||||
FREE(d->mallocarea);
|
FREE(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -77,8 +77,8 @@ struct dfa
|
|||||||
chr *lastpost; /* location of last cache-flushed success */
|
chr *lastpost; /* location of last cache-flushed success */
|
||||||
chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
|
chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
|
||||||
struct sset *search; /* replacement-search-pointer memory */
|
struct sset *search; /* replacement-search-pointer memory */
|
||||||
int cptsmalloced; /* were the areas individually malloced? */
|
bool ismalloced; /* should this struct dfa be freed? */
|
||||||
char *mallocarea; /* self, or master malloced area, or NULL */
|
bool arraysmalloced; /* should its subsidiary arrays be freed? */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WORK 1 /* number of work bitvectors needed */
|
#define WORK 1 /* number of work bitvectors needed */
|
||||||
@ -88,7 +88,7 @@ struct dfa
|
|||||||
#define FEWCOLORS 15
|
#define FEWCOLORS 15
|
||||||
struct smalldfa
|
struct smalldfa
|
||||||
{
|
{
|
||||||
struct dfa dfa;
|
struct dfa dfa; /* must be first */
|
||||||
struct sset ssets[FEWSTATES * 2];
|
struct sset ssets[FEWSTATES * 2];
|
||||||
unsigned statesarea[FEWSTATES * 2 + WORK];
|
unsigned statesarea[FEWSTATES * 2 + WORK];
|
||||||
struct sset *outsarea[FEWSTATES * 2 * FEWCOLORS];
|
struct sset *outsarea[FEWSTATES * 2 * FEWCOLORS];
|
||||||
|
Loading…
Reference in New Issue
Block a user