summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Baker-Smith <bbakersmith@gmail.com>2020-02-13 09:58:07 -0500
committerDaniel Stenberg <daniel@haxx.se>2020-02-28 08:07:24 +0100
commit496fcdfbd7a482b7bf78de41378e16bb4ab888c5 (patch)
tree4a843a0e2e4d97659c868872e9876a5ce2b1a15d
parent1f114be62621ba756d7c0f8c96eb35505a4a020b (diff)
downloadcurl-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_BUGS7
-rw-r--r--src/tool_getparam.c46
-rw-r--r--tests/data/test10156
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>