]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
urlapi: URL encode a '+' in the query part
authorDaniel Stenberg <daniel@haxx.se>
Thu, 15 Oct 2020 10:22:27 +0000 (12:22 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 15 Oct 2020 21:21:53 +0000 (23:21 +0200)
... when asked to with CURLU_URLENCODE.

Extended test 1560 to verify.
Reported-by: Dietmar Hauser
Fixes #6086
Closes #6087

lib/urlapi.c
tests/libtest/lib1560.c

index 88b7f042f43427d275561700b0c53bc776734f67..c429d92ab3c137c26b5cef286bb6455c79a46241 100644 (file)
@@ -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;
index cc61199e989d3a65f63ec21041b267356e40946b..387ee8dadcde3e17458d4a77fdd8e1f96685073f 100644 (file)
@@ -478,6 +478,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,",