Prevent corner-case core dump in rfree().

rfree() failed to cope with the case that pg_regcomp() had initialized the
regex_t struct but then failed to allocate any memory for re->re_guts (ie,
the first malloc call in pg_regcomp() failed).  It would try to touch the
guts struct anyway, and thus dump core.  This is a sufficiently narrow
corner case that it's not surprising it's never been seen in the field;
but still a bug is a bug, so patch all active branches.

Noted while investigating whether we need to call pg_regfree after a
failure return from pg_regcomp.  Other than this bug, it turns out we
don't, so adjust comments appropriately.
This commit is contained in:
Tom Lane 2012-07-15 13:27:54 -04:00
parent 2686da9db2
commit 54fd196ffc
2 changed files with 16 additions and 11 deletions

View File

@ -278,6 +278,9 @@ static struct fns functions = {
/*
* pg_regcomp - compile regular expression
*
* Note: on failure, no resources remain allocated, so pg_regfree()
* need not be applied to re.
*/
int
pg_regcomp(regex_t *re,
@ -1870,15 +1873,18 @@ rfree(regex_t *re)
g = (struct guts *) re->re_guts;
re->re_guts = NULL;
re->re_fns = NULL;
g->magic = 0;
freecm(&g->cmap);
if (g->tree != NULL)
freesubre((struct vars *) NULL, g->tree);
if (g->lacons != NULL)
freelacons(g->lacons, g->nlacons);
if (!NULLCNFA(g->search))
freecnfa(&g->search);
FREE(g);
if (g != NULL)
{
g->magic = 0;
freecm(&g->cmap);
if (g->tree != NULL)
freesubre((struct vars *) NULL, g->tree);
if (g->lacons != NULL)
freelacons(g->lacons, g->nlacons);
if (!NULLCNFA(g->search))
freecnfa(&g->search);
FREE(g);
}
}
#ifdef REG_DEBUG

View File

@ -187,9 +187,8 @@ RE_compile_and_cache(text *text_re, int cflags, Oid collation)
if (regcomp_result != REG_OKAY)
{
/* re didn't compile */
/* re didn't compile (no need for pg_regfree, if so) */
pg_regerror(regcomp_result, &re_temp.cre_re, errMsg, sizeof(errMsg));
/* XXX should we pg_regfree here? */
ereport(ERROR,
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
errmsg("invalid regular expression: %s", errMsg)));