Fix some memory leaks associated with parsing json and manifests

Coverity complained about not freeing some memory associated with
incrementally parsing backup manifests. To fix that, provide and use a new
shutdown function for the JsonManifestParseIncrementalState object, in
line with a suggestion from Tom Lane.

While analysing the problem, I noticed a buglet in freeing memory for
incremental json lexers. To fix that remove a bogus condition on
freeing the memory allocated for them.
This commit is contained in:
Andrew Dunstan 2024-04-09 09:07:14 -04:00
parent b9ecefecc7
commit 661ab4e185
6 changed files with 32 additions and 12 deletions

View File

@ -241,6 +241,9 @@ FinalizeIncrementalManifest(IncrementalBackupInfo *ib)
pfree(ib->buf.data);
ib->buf.data = NULL;
/* Done with inc_state, so release that memory too */
json_parse_manifest_incremental_shutdown(ib->inc_state);
/* Switch back to previous memory context. */
MemoryContextSwitchTo(oldcontext);
}

View File

@ -208,6 +208,9 @@ load_backup_manifest(char *backup_directory)
inc_state, buffer, rc, bytes_left == 0);
}
/* Release the incremental state memory */
json_parse_manifest_incremental_shutdown(inc_state);
close(fd);
}

View File

@ -484,6 +484,9 @@ parse_manifest_file(char *manifest_path)
inc_state, buffer, rc, bytes_left == 0);
}
/* Release the incremental state memory */
json_parse_manifest_incremental_shutdown(inc_state);
close(fd);
}

View File

@ -488,19 +488,18 @@ freeJsonLexContext(JsonLexContext *lex)
if (lex->errormsg)
destroyStringInfo(lex->errormsg);
if (lex->flags & JSONLEX_FREE_STRUCT)
if (lex->incremental)
{
if (lex->incremental)
{
pfree(lex->inc_state->partial_token.data);
pfree(lex->inc_state);
pfree(lex->pstack->prediction);
pfree(lex->pstack->fnames);
pfree(lex->pstack->fnull);
pfree(lex->pstack);
}
pfree(lex);
pfree(lex->inc_state->partial_token.data);
pfree(lex->inc_state);
pfree(lex->pstack->prediction);
pfree(lex->pstack->fnames);
pfree(lex->pstack->fnull);
pfree(lex->pstack);
}
if (lex->flags & JSONLEX_FREE_STRUCT)
pfree(lex);
}
/*

View File

@ -123,7 +123,6 @@ static bool parse_xlogrecptr(XLogRecPtr *result, char *input);
/*
* Set up for incremental parsing of the manifest.
*
*/
JsonManifestParseIncrementalState *
@ -163,6 +162,18 @@ json_parse_manifest_incremental_init(JsonManifestParseContext *context)
return incstate;
}
/*
* Free an incremental state object and its contents.
*/
void
json_parse_manifest_incremental_shutdown(JsonManifestParseIncrementalState *incstate)
{
pfree(incstate->sem.semstate);
freeJsonLexContext(&(incstate->lex));
/* incstate->manifest_ctx has already been freed */
pfree(incstate);
}
/*
* parse the manifest in pieces.
*

View File

@ -53,5 +53,6 @@ extern JsonManifestParseIncrementalState *json_parse_manifest_incremental_init(J
extern void json_parse_manifest_incremental_chunk(
JsonManifestParseIncrementalState *incstate, char *chunk, int size,
bool is_last);
extern void json_parse_manifest_incremental_shutdown(JsonManifestParseIncrementalState *incstate);
#endif