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 ad051e1cbe

Closes #12289
This commit is contained in:
Daniel Stenberg 2023-11-07 10:58:08 +01:00
parent 36662c3860
commit 82ba603da4
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 27 additions and 26 deletions

View File

@ -849,13 +849,17 @@ static const struct Curl_cwtype * const encodings[] = {
}; };
/* Return a list of comma-separated names of supported encodings. */ /* Provide a list of comma-separated names of supported encodings.
char *Curl_all_content_encodings(void) */
void Curl_all_content_encodings(char *buf, size_t blen)
{ {
size_t len = 0; size_t len = 0;
const struct Curl_cwtype * const *cep; const struct Curl_cwtype * const *cep;
const struct Curl_cwtype *ce; const struct Curl_cwtype *ce;
char *ace;
DEBUGASSERT(buf);
DEBUGASSERT(blen);
buf[0] = 0;
for(cep = encodings; *cep; cep++) { for(cep = encodings; *cep; cep++) {
ce = *cep; ce = *cep;
@ -863,12 +867,12 @@ char *Curl_all_content_encodings(void)
len += strlen(ce->name) + 2; len += strlen(ce->name) + 2;
} }
if(!len) if(!len) {
return strdup(CONTENT_ENCODING_DEFAULT); if(blen >= sizeof(CONTENT_ENCODING_DEFAULT))
strcpy(buf, CONTENT_ENCODING_DEFAULT);
ace = malloc(len); }
if(ace) { else if(blen > len) {
char *p = ace; char *p = buf;
for(cep = encodings; *cep; cep++) { for(cep = encodings; *cep; cep++) {
ce = *cep; ce = *cep;
if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) { if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) {
@ -880,11 +884,8 @@ char *Curl_all_content_encodings(void)
} }
p[-2] = '\0'; p[-2] = '\0';
} }
return ace;
} }
/* Deferred error dummy writer. */ /* Deferred error dummy writer. */
static CURLcode error_do_init(struct Curl_easy *data, static CURLcode error_do_init(struct Curl_easy *data,
struct Curl_cwriter *writer) struct Curl_cwriter *writer)
@ -898,7 +899,8 @@ static CURLcode error_do_write(struct Curl_easy *data,
struct Curl_cwriter *writer, int type, struct Curl_cwriter *writer, int type,
const char *buf, size_t nbytes) 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) writer;
(void) buf; (void) buf;
@ -907,11 +909,8 @@ static CURLcode error_do_write(struct Curl_easy *data,
if(!(type & CLIENTWRITE_BODY)) if(!(type & CLIENTWRITE_BODY))
return Curl_cwriter_write(data, writer->next, type, buf, nbytes); return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
if(!all)
return CURLE_OUT_OF_MEMORY;
failf(data, "Unrecognized content encoding type. " failf(data, "Unrecognized content encoding type. "
"libcurl understands %s content encodings.", all); "libcurl understands %s content encodings.", all);
free(all);
return CURLE_BAD_CONTENT_ENCODING; return CURLE_BAD_CONTENT_ENCODING;
} }
@ -1021,9 +1020,15 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
return CURLE_NOT_BUILT_IN; 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 */ #endif /* CURL_DISABLE_HTTP */

View File

@ -27,7 +27,7 @@
struct Curl_cwriter; 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, CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
const char *enclist, int is_transfer); const char *enclist, int is_transfer);

View File

@ -592,13 +592,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
*/ */
argptr = va_arg(param, char *); argptr = va_arg(param, char *);
if(argptr && !*argptr) { if(argptr && !*argptr) {
argptr = Curl_all_content_encodings(); char all[256];
if(!argptr) Curl_all_content_encodings(all, sizeof(all));
result = CURLE_OUT_OF_MEMORY; result = Curl_setstropt(&data->set.str[STRING_ENCODING], all);
else {
result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
free(argptr);
}
} }
else else
result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);