From 70e4c02beb73b92f5c85a4d8f82ad938d7a075b5 Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Thu, 25 Apr 2024 15:26:40 -0700 Subject: [PATCH] WIP: fix leak of scalar value on lex failure TODO: field names --- src/common/jsonapi.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/common/jsonapi.c b/src/common/jsonapi.c index 6633503490..6339e909a4 100644 --- a/src/common/jsonapi.c +++ b/src/common/jsonapi.c @@ -380,10 +380,9 @@ makeJsonLexContextIncremental(JsonLexContext *lex, int encoding, lex->incremental = true; lex->inc_state = palloc0(sizeof(JsonIncrementalState)); initStringInfo(&(lex->inc_state->partial_token)); - lex->pstack = palloc(sizeof(JsonParserStack)); + lex->pstack = palloc0(sizeof(JsonParserStack)); lex->pstack->stack_size = JS_STACK_CHUNK_SIZE; lex->pstack->prediction = palloc(JS_STACK_CHUNK_SIZE * JS_MAX_PROD_LEN); - lex->pstack->pred_index = 0; lex->pstack->fnames = palloc(JS_STACK_CHUNK_SIZE * sizeof(char *)); lex->pstack->fnull = palloc(JS_STACK_CHUNK_SIZE * sizeof(bool)); if (need_escapes) @@ -495,6 +494,7 @@ freeJsonLexContext(JsonLexContext *lex) pfree(lex->pstack->prediction); pfree(lex->pstack->fnames); pfree(lex->pstack->fnull); + pfree(lex->pstack->scalar_val); pfree(lex->pstack); } @@ -912,6 +912,13 @@ pg_parse_json_incremental(JsonLexContext *lex, if (sfunc != NULL) { result = (*sfunc) (sem->semstate, pstack->scalar_val, pstack->scalar_tok); + + /* + * Ownership of the token allocation has passed to + * the callback; don't free it later. + */ + pstack->scalar_val = NULL; + if (result != JSON_SUCCESS) return result; } @@ -1040,9 +1047,12 @@ parse_scalar(JsonLexContext *lex, JsonSemAction *sem) /* consume the token */ result = json_lex(lex); if (result != JSON_SUCCESS) + { + pfree(val); return result; + } - /* invoke the callback */ + /* invoke the callback, which takes ownership of val */ result = (*sfunc) (sem->semstate, val, tok); return result; -- 2.34.1