diff options
author | Daniel Stenberg <daniel@haxx.se> | 2020-10-01 22:59:30 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-10-02 09:35:37 +0200 |
commit | 3997b3e2a4bcf0023d277a74b6187cdad46533b2 (patch) | |
tree | b6a9dfe3f637e09f2e472f570dbc445c6218c69d /src/tool_setopt.c | |
parent | 9a13f7c2a7ca5fca99622a6feeb29abc3b05d713 (diff) | |
download | curl-3997b3e2a4bcf0023d277a74b6187cdad46533b2.tar.gz |
curl: make --libcurl show binary posts correctly
Reported-by: Stephan Mühlstrasser
Fixes #6031
Closes #6032
Diffstat (limited to 'src/tool_setopt.c')
-rw-r--r-- | src/tool_setopt.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/src/tool_setopt.c b/src/tool_setopt.c index 9858d49c9..ea23e9386 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -219,26 +219,34 @@ static const struct NameValue setopt_nv_CURLNONZERODEFAULTS[] = { /* Escape string to C string syntax. Return NULL if out of memory. * Is this correct for those wacky EBCDIC guys? */ -static char *c_escape(const char *str, size_t len) + +#define MAX_STRING_LENGTH_OUTPUT 2000 +#define ZERO_TERMINATED -1 + +static char *c_escape(const char *str, curl_off_t len) { const char *s; unsigned char c; char *escaped, *e; + unsigned int cutoff = 0; - if(len == CURL_ZERO_TERMINATED) + if(len == ZERO_TERMINATED) len = strlen(str); - /* Check for possible overflow. */ - if(len > (~(size_t) 0) / 4) - return NULL; + if(len > MAX_STRING_LENGTH_OUTPUT) { + /* cap ridiculously long strings */ + len = MAX_STRING_LENGTH_OUTPUT; + cutoff = 3; + } /* Allocate space based on worst-case */ - escaped = malloc(4 * len + 1); + escaped = malloc(4 * (size_t)len + 1 + cutoff); if(!escaped) return NULL; e = escaped; - for(s = str; (c = *s) != '\0'; s++) { + for(s = str; len; s++, len--) { + c = *s; if(c == '\n') { strcpy(e, "\\n"); e += 2; @@ -266,6 +274,8 @@ static char *c_escape(const char *str, size_t len) else *e++ = c; } + while(cutoff--) + *e++ = '.'; *e = '\0'; return escaped; } @@ -404,7 +414,7 @@ static CURLcode libcurl_generate_slist(struct curl_slist *slist, int *slistno) CLEAN1("slist%d = NULL;", *slistno); for(; slist; slist = slist->next) { Curl_safefree(escaped); - escaped = c_escape(slist->data, CURL_ZERO_TERMINATED); + escaped = c_escape(slist->data, ZERO_TERMINATED); if(!escaped) return CURLE_OUT_OF_MEMORY; DATA3("slist%d = curl_slist_append(slist%d, \"%s\");", @@ -455,7 +465,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl, case TOOLMIME_DATA: #ifdef CURL_DOES_CONVERSIONS /* Data will be set in ASCII, thus issue a comment with clear text. */ - escaped = c_escape(part->data, CURL_ZERO_TERMINATED); + escaped = c_escape(part->data, ZERO_TERMINATED); NULL_CHECK(escaped); CODE1("/* \"%s\" */", escaped); @@ -474,7 +484,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl, #endif if(!ret) { Curl_safefree(escaped); - escaped = c_escape(data, CURL_ZERO_TERMINATED); + escaped = c_escape(data, ZERO_TERMINATED); NULL_CHECK(escaped); CODE2("curl_mime_data(part%d, \"%s\", CURL_ZERO_TERMINATED);", mimeno, escaped); @@ -483,7 +493,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl, case TOOLMIME_FILE: case TOOLMIME_FILEDATA: - escaped = c_escape(part->data, CURL_ZERO_TERMINATED); + escaped = c_escape(part->data, ZERO_TERMINATED); NULL_CHECK(escaped); CODE2("curl_mime_filedata(part%d, \"%s\");", mimeno, escaped); if(part->kind == TOOLMIME_FILEDATA && !filename) { @@ -508,28 +518,28 @@ static CURLcode libcurl_generate_mime_part(CURL *curl, if(!ret && part->encoder) { Curl_safefree(escaped); - escaped = c_escape(part->encoder, CURL_ZERO_TERMINATED); + escaped = c_escape(part->encoder, ZERO_TERMINATED); NULL_CHECK(escaped); CODE2("curl_mime_encoder(part%d, \"%s\");", mimeno, escaped); } if(!ret && filename) { Curl_safefree(escaped); - escaped = c_escape(filename, CURL_ZERO_TERMINATED); + escaped = c_escape(filename, ZERO_TERMINATED); NULL_CHECK(escaped); CODE2("curl_mime_filename(part%d, \"%s\");", mimeno, escaped); } if(!ret && part->name) { Curl_safefree(escaped); - escaped = c_escape(part->name, CURL_ZERO_TERMINATED); + escaped = c_escape(part->name, ZERO_TERMINATED); NULL_CHECK(escaped); CODE2("curl_mime_name(part%d, \"%s\");", mimeno, escaped); } if(!ret && part->type) { Curl_safefree(escaped); - escaped = c_escape(part->type, CURL_ZERO_TERMINATED); + escaped = c_escape(part->type, ZERO_TERMINATED); NULL_CHECK(escaped); CODE2("curl_mime_type(part%d, \"%s\");", mimeno, escaped); } @@ -623,7 +633,8 @@ CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config, /* generic setopt wrapper for all other options. * Some type information is encoded in the tag value. */ -CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config, +CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global, + struct OperationConfig *config, const char *name, CURLoption tag, ...) { va_list arg; @@ -711,14 +722,17 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config, va_end(arg); - if(config->libcurl && !skip && !ret) { + if(global->libcurl && !skip && !ret) { /* we only use this for real if --libcurl was used */ if(remark) REM2("%s set to a %s", name, value); else { if(escape) { - escaped = c_escape(value, CURL_ZERO_TERMINATED); + curl_off_t len = ZERO_TERMINATED; + if(tag == CURLOPT_POSTFIELDS) + len = config->postfieldsize; + escaped = c_escape(value, len); NULL_CHECK(escaped); CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped); } |