diff options
author | Ben Baker-Smith <bbakersmith@gmail.com> | 2020-02-13 09:58:07 -0500 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-02-28 08:07:24 +0100 |
commit | 496fcdfbd7a482b7bf78de41378e16bb4ab888c5 (patch) | |
tree | 4a843a0e2e4d97659c868872e9876a5ce2b1a15d | |
parent | 1f114be62621ba756d7c0f8c96eb35505a4a020b (diff) | |
download | curl-496fcdfbd7a482b7bf78de41378e16bb4ab888c5.tar.gz |
tool_getparam: escape spaces in form content with +
According to RFC1866, in form-urlencoded content "space characters are
replaced by `+', and then reserved characters are escaped as per URL."
Fixes #3229
Closes #4924
Closes #4987
-rw-r--r-- | docs/KNOWN_BUGS | 7 | ||||
-rw-r--r-- | src/tool_getparam.c | 46 | ||||
-rw-r--r-- | tests/data/test1015 | 6 |
3 files changed, 45 insertions, 14 deletions
diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS index 351eca29f..5ffb5f078 100644 --- a/docs/KNOWN_BUGS +++ b/docs/KNOWN_BUGS @@ -338,13 +338,6 @@ problems may have been fixed or changed somewhat since this was written! See https://github.com/curl/curl/issues/2051 -4.5 Improve --data-urlencode space encoding - - ASCII space characters in --data-urlencode are currently encoded as %20 - rather than +, which RFC 1866 says should be used. - - See https://github.com/curl/curl/issues/3229 - 5. Build and portability issues 5.1 USE_UNIX_SOCKETS on Windows diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 764caa203..638f138ea 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -498,6 +498,36 @@ static ParameterError GetSizeParameter(struct GlobalConfig *global, return PARAM_OK; } +/* fix space encoding per RFC1866 */ +static char *replace_url_encoded_space_with_plus(const char *in) +{ + size_t inlen = strlen(in); + size_t in_index = 0; + size_t out_index = 0; + + char *out = malloc(inlen + 1); + if(!out) + return NULL; + + while(in_index < inlen) { + if((in[in_index] == '%') && + (in[in_index + 1] == '2') && + (in[in_index + 2] == '0')) { + out[out_index] = '+'; + in_index += 3; + } + else { + out[out_index] = in[in_index]; + in_index++; + } + out_index++; + } + + out[out_index] = 0; /* terminate string */ + + return out; +} + ParameterError getparameter(const char *flag, /* f or -long-flag */ char *nextarg, /* NULL if unset */ bool *usedarg, /* set to TRUE if the arg @@ -1387,12 +1417,20 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ char *enc = curl_easy_escape(NULL, postdata, (int)size); Curl_safefree(postdata); /* no matter if it worked or not */ if(enc) { + size_t outlen; + char *n; + char *reenc = replace_url_encoded_space_with_plus(enc); + curl_free(enc); + if(!reenc) + return PARAM_NO_MEM; + enc = reenc; + /* now make a string with the name from above and append the encoded string */ - size_t outlen = nlen + strlen(enc) + 2; - char *n = malloc(outlen); + outlen = nlen + strlen(enc) + 2; + n = malloc(outlen); if(!n) { - curl_free(enc); + free(enc); return PARAM_NO_MEM; } if(nlen > 0) { /* only append '=' if we have a name */ @@ -1403,7 +1441,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ strcpy(n, enc); size = outlen-2; /* since no '=' was inserted */ } - curl_free(enc); + free(enc); postdata = n; } else diff --git a/tests/data/test1015 b/tests/data/test1015 index a2b2cefa1..6d9286010 100644 --- a/tests/data/test1015 +++ b/tests/data/test1015 @@ -28,7 +28,7 @@ http --data-urlencode </name> <command> -http://%HOSTIP:%HTTPPORT/1015 --data-urlencode "my name is moo[]" --data-urlencode "y e s=s_i_r" --data-urlencode "v_alue@log/1015.txt" --data-urlencode @log/1015.txt +http://%HOSTIP:%HTTPPORT/1015 --data-urlencode "my name is moo[] " --data-urlencode "y e s=s_i r" --data-urlencode "v_alue@log/1015.txt" --data-urlencode @log/1015.txt --data-urlencode double%20encoded </command> <file name="log/1015.txt"> content to _?!#$'|<> @@ -46,10 +46,10 @@ POST /1015 HTTP/1.1 User-Agent: curl/7.17.2-CVS (i686-pc-linux-gnu) libcurl/7.17.2-CVS OpenSSL/0.9.8g zlib/1.2.3.3 c-ares/1.5.2-CVS libidn/1.1 libssh2/0.19.0-C
Host: %HOSTIP:%HTTPPORT
Accept: */*
-Content-Length: 133
+Content-Length: 139
Content-Type: application/x-www-form-urlencoded
-my%20name%20is%20moo%5B%5D&y e s=s_i_r&v_alue=content%20to%20_%3F%21%23%24%27%7C%3C%3E%0A&content%20to%20_%3F%21%23%24%27%7C%3C%3E%0A +my+name+is+moo%5B%5D+&y e s=s_i+r&v_alue=content+to+_%3F%21%23%24%27%7C%3C%3E%0A&content+to+_%3F%21%23%24%27%7C%3C%3E%0A&double%2520encoded </protocol> </verify> </testcase> |