summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2020-10-15 12:22:27 +0200
committerDaniel Stenberg <daniel@haxx.se>2020-10-15 23:21:53 +0200
commitb7ea3d2c22fe76fd85d1c5c6672829960d1d6e36 (patch)
tree18dff79cd3acc1f7404d729c56fd6dfb05f2ce51
parent3862c37b6373a55ca704171d45ba5ee91dec2c9f (diff)
downloadcurl-b7ea3d2c22fe76fd85d1c5c6672829960d1d6e36.tar.gz
urlapi: URL encode a '+' in the query part
... when asked to with CURLU_URLENCODE. Extended test 1560 to verify. Reported-by: Dietmar Hauser Fixes #6086 Closes #6087
-rw-r--r--lib/urlapi.c27
-rw-r--r--tests/libtest/lib1560.c7
2 files changed, 14 insertions, 20 deletions
diff --git a/lib/urlapi.c b/lib/urlapi.c
index 88b7f042f..c429d92ab 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -1387,28 +1387,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
if(urlencode) {
const unsigned char *i;
char *o;
- bool free_part = FALSE;
char *enc = malloc(nalloc * 3 + 1); /* for worst case! */
if(!enc)
return CURLUE_OUT_OF_MEMORY;
- if(plusencode) {
- /* space to plus */
- i = (const unsigned char *)part;
- for(o = enc; *i; ++o, ++i)
- *o = (*i == ' ') ? '+' : *i;
- *o = 0; /* null-terminate */
- part = strdup(enc);
- if(!part) {
- free(enc);
- return CURLUE_OUT_OF_MEMORY;
- }
- free_part = TRUE;
- }
for(i = (const unsigned char *)part, o = enc; *i; i++) {
- if(Curl_isunreserved(*i) ||
- ((*i == '/') && urlskipslash) ||
- ((*i == '=') && equalsencode) ||
- ((*i == '+') && plusencode)) {
+ if((*i == ' ') && plusencode) {
+ *o = '+';
+ o++;
+ }
+ else if(Curl_isunreserved(*i) ||
+ ((*i == '/') && urlskipslash) ||
+ ((*i == '=') && equalsencode)) {
if((*i == '=') && equalsencode)
/* only skip the first equals sign */
equalsencode = FALSE;
@@ -1422,8 +1411,6 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
}
*o = 0; /* null-terminate */
newp = enc;
- if(free_part)
- free((char *)part);
}
else {
char *p;
diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c
index cc61199e9..387ee8dad 100644
--- a/tests/libtest/lib1560.c
+++ b/tests/libtest/lib1560.c
@@ -479,6 +479,13 @@ static int checkurl(const char *url, const char *out)
/* !checksrc! disable SPACEBEFORECOMMA 1 */
static struct setcase set_parts_list[] = {
{"https://example.com/",
+ "query=Al2cO3tDkcDZ3EWE5Lh+LX8TPHs,", /* contains '+' */
+ "https://example.com/?Al2cO3tDkcDZ3EWE5Lh%2bLX8TPHs",
+ CURLU_URLDECODE, /* decode on get */
+ CURLU_URLENCODE, /* encode on set */
+ CURLUE_OK, CURLUE_OK},
+
+ {"https://example.com/",
/* Set a 41 bytes scheme. That's too long so the old scheme remains set. */
"scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc,",
"https://example.com/",