From 82ba603da44b9f066d07a074b3e73b08d0ce98b0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 7 Nov 2023 10:58:08 +0100 Subject: [PATCH] content_encoding: make Curl_all_content_encodings allocless - Fixes a memory leak pointed out by Coverity - Also found by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63947 - Avoids unncessary allocations Follow-up ad051e1cbec68b2456a22661b Closes #12289 --- lib/content_encoding.c | 41 +++++++++++++++++++++++------------------ lib/content_encoding.h | 2 +- lib/setopt.c | 10 +++------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/content_encoding.c b/lib/content_encoding.c index c7553e15a..4167d4d68 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -849,13 +849,17 @@ static const struct Curl_cwtype * const encodings[] = { }; -/* Return a list of comma-separated names of supported encodings. */ -char *Curl_all_content_encodings(void) +/* Provide a list of comma-separated names of supported encodings. +*/ +void Curl_all_content_encodings(char *buf, size_t blen) { size_t len = 0; const struct Curl_cwtype * const *cep; const struct Curl_cwtype *ce; - char *ace; + + DEBUGASSERT(buf); + DEBUGASSERT(blen); + buf[0] = 0; for(cep = encodings; *cep; cep++) { ce = *cep; @@ -863,12 +867,12 @@ char *Curl_all_content_encodings(void) len += strlen(ce->name) + 2; } - if(!len) - return strdup(CONTENT_ENCODING_DEFAULT); - - ace = malloc(len); - if(ace) { - char *p = ace; + if(!len) { + if(blen >= sizeof(CONTENT_ENCODING_DEFAULT)) + strcpy(buf, CONTENT_ENCODING_DEFAULT); + } + else if(blen > len) { + char *p = buf; for(cep = encodings; *cep; cep++) { ce = *cep; if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) { @@ -880,11 +884,8 @@ char *Curl_all_content_encodings(void) } p[-2] = '\0'; } - - return ace; } - /* Deferred error dummy writer. */ static CURLcode error_do_init(struct Curl_easy *data, struct Curl_cwriter *writer) @@ -898,7 +899,8 @@ static CURLcode error_do_write(struct Curl_easy *data, struct Curl_cwriter *writer, int type, const char *buf, size_t nbytes) { - char *all = Curl_all_content_encodings(); + char all[256]; + (void)Curl_all_content_encodings(all, sizeof(all)); (void) writer; (void) buf; @@ -907,11 +909,8 @@ static CURLcode error_do_write(struct Curl_easy *data, if(!(type & CLIENTWRITE_BODY)) return Curl_cwriter_write(data, writer->next, type, buf, nbytes); - if(!all) - return CURLE_OUT_OF_MEMORY; failf(data, "Unrecognized content encoding type. " "libcurl understands %s content encodings.", all); - free(all); return CURLE_BAD_CONTENT_ENCODING; } @@ -1021,9 +1020,15 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, return CURLE_NOT_BUILT_IN; } -char *Curl_all_content_encodings(void) +void Curl_all_content_encodings(char *buf, size_t blen) { - return strdup(CONTENT_ENCODING_DEFAULT); /* Satisfy caller. */ + DEBUGASSERT(buf); + DEBUGASSERT(blen); + if(blen < sizeof(CONTENT_ENCODING_DEFAULT)) + buf[0] = 0; + else + strcpy(buf, CONTENT_ENCODING_DEFAULT); } + #endif /* CURL_DISABLE_HTTP */ diff --git a/lib/content_encoding.h b/lib/content_encoding.h index 7b71c813c..1addf230b 100644 --- a/lib/content_encoding.h +++ b/lib/content_encoding.h @@ -27,7 +27,7 @@ struct Curl_cwriter; -char *Curl_all_content_encodings(void); +void Curl_all_content_encodings(char *buf, size_t blen); CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, const char *enclist, int is_transfer); diff --git a/lib/setopt.c b/lib/setopt.c index 5178feaea..c3ff34fac 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -592,13 +592,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ argptr = va_arg(param, char *); if(argptr && !*argptr) { - argptr = Curl_all_content_encodings(); - if(!argptr) - result = CURLE_OUT_OF_MEMORY; - else { - result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); - free(argptr); - } + char all[256]; + Curl_all_content_encodings(all, sizeof(all)); + result = Curl_setstropt(&data->set.str[STRING_ENCODING], all); } else result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);