From e61304306bba74122c21cf92cc7620db8862b67d Mon Sep 17 00:00:00 2001 From: Costa Tsaousis Date: Thu, 2 Oct 2025 00:28:15 +0300 Subject: [PATCH] fix(aclk): free previous header values before overwrite Refs: netdata/netdata#21083 --- src/aclk/https_client.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/aclk/https_client.c b/src/aclk/https_client.c index 38adac5fb67293..105229bd472a20 100644 --- a/src/aclk/https_client.c +++ b/src/aclk/https_client.c @@ -147,15 +147,6 @@ static const char *http_req_type_to_str(http_req_type_t req) { #define TRANSFER_ENCODING_CHUNKED (-2) -void http_parse_ctx_create(http_parse_ctx *ctx, enum http_parse_state parse_state) -{ - ctx->state = parse_state; - ctx->content_length = -1; - ctx->http_code = 0; - ctx->headers = c_rhash_new(0); - ctx->flags = HTTP_PARSE_FLAGS_DEFAULT; -} - void http_parse_ctx_destroy(http_parse_ctx *ctx) { if(!ctx->headers) @@ -175,6 +166,23 @@ void http_parse_ctx_destroy(http_parse_ctx *ctx) ctx->headers = NULL; } +void http_parse_ctx_create(http_parse_ctx *ctx, enum http_parse_state parse_state) +{ + http_parse_ctx_destroy(ctx); + + ctx->state = parse_state; + ctx->content_length = -1; + ctx->http_code = 0; + ctx->headers = c_rhash_new(0); + ctx->flags = HTTP_PARSE_FLAGS_DEFAULT; + ctx->chunked_content_state = CHUNKED_CONTENT_CHUNK_SIZE; + ctx->chunk_size = 0; + ctx->chunk_got = 0; + ctx->chunked_response_written = 0; + ctx->chunked_response_size = 0; + ctx->chunked_response = NULL; +} + #define POLL_TO_MS 100 #define HTTP_LINE_TERM "\x0D\x0A" @@ -214,6 +222,10 @@ static int process_http_hdr(http_parse_ctx *parse_ctx, const char *key, const ch } return 0; } + void *prev_val = NULL; + if (!c_rhash_get_ptr_by_str(parse_ctx->headers, key, &prev_val)) + freez(prev_val); // drop previous allocation before overwriting + char *val_cpy = strdupz(val); c_rhash_insert_str_ptr(parse_ctx->headers, key, val_cpy); return 0; @@ -710,8 +722,12 @@ static https_client_resp_t handle_http_request(https_req_ctx_t *ctx) { rc = read_parse_response(ctx); if (rc != HTTPS_CLIENT_RESP_OK) { netdata_log_error("ACLK: error reading or parsing response from server"); - if (ctx->parse_ctx.chunked_response) + if (ctx->parse_ctx.chunked_response) { freez(ctx->parse_ctx.chunked_response); + ctx->parse_ctx.chunked_response = NULL; + ctx->parse_ctx.chunked_response_size = 0; + ctx->parse_ctx.chunked_response_written = 0; + } } err_exit: @@ -887,6 +903,9 @@ https_client_resp_t https_request(https_req_t *request, https_req_response_t *re if (ctx->parse_ctx.content_length == TRANSFER_ENCODING_CHUNKED) { response->payload_size = ctx->parse_ctx.chunked_response_size; response->payload = ctx->parse_ctx.chunked_response; + ctx->parse_ctx.chunked_response = NULL; + ctx->parse_ctx.chunked_response_size = 0; + ctx->parse_ctx.chunked_response_written = 0; } if (ctx->parse_ctx.content_length > 0) { response->payload_size = ctx->parse_ctx.content_length; @@ -918,6 +937,7 @@ https_client_resp_t https_request(https_req_t *request, https_req_response_t *re exit_buf_rx: rbuf_free(ctx->buf_rx); exit_req_ctx: + http_parse_ctx_destroy(&ctx->parse_ctx); freez(ctx); return rc; }