]> granicus.if.org Git - curl/commitdiff
urlapi: only skip encoding the first '=' with APPENDQUERY set
authorDaniel Stenberg <daniel@haxx.se>
Tue, 6 Nov 2018 22:48:35 +0000 (23:48 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 7 Nov 2018 07:28:48 +0000 (08:28 +0100)
APPENDQUERY + URLENCODE would skip all equals signs but now it only skip
encoding the first to better allow "name=content" for any content.

Reported-by: Alexey Melnichuk
Fixes #3231
Closes #3231

docs/libcurl/curl_url_set.3
lib/urlapi.c
tests/libtest/lib1560.c

index 4ecfcafa04ce075b02c8ec2c9e3e9cbef8ed409d..4c8ff9810d69c0862b2d52822e5251a29d6ab572 100644 (file)
@@ -71,12 +71,13 @@ automatically when this URL is read from the handle.
 The query part will also get spaces converted to pluses when asked to URL
 encode on set with the CURLU_URLENCODE bit.
 
-If used in with \fICURLU_APPENDQUERY\fP, the provided part will be appended on
-the end of the existing query - and if the previous part didn't end with an
-ampersand (&), an ampersand will be inserted before the new appended part.
+If used together with the \fICURLU_APPENDQUERY\fP bit, the provided part will
+be appended on the end of the existing query - and if the previous part didn't
+end with an ampersand (&), an ampersand will be inserted before the new
+appended part.
 
-When \fICURLU_APPENDQUERY\fP is used together with \fICURLU_URLENCODE\fP,
-the '=' symbols will not be URL encoded.
+When \fICURLU_APPENDQUERY\fP is used together with \fICURLU_URLENCODE\fP, the
+first '=' symbol will not be URL encoded.
 
 The question mark in the URL is not part of the actual query contents.
 .IP CURLUPART_FRAGMENT
index e877dc726149ee47196753b99febcc75f2b3ec2b..2830dc163bdf0605e0d950658b91568ab82271dd 100644 (file)
@@ -1103,6 +1103,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
   bool plusencode = FALSE;
   bool urlskipslash = FALSE;
   bool appendquery = FALSE;
+  bool equalsencode = FALSE;
 
   if(!u)
     return CURLUE_BAD_HANDLE;
@@ -1183,6 +1184,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
   case CURLUPART_QUERY:
     plusencode = urlencode;
     appendquery = (flags & CURLU_APPENDQUERY)?1:0;
+    equalsencode = appendquery;
     storep = &u->query;
     break;
   case CURLUPART_FRAGMENT:
@@ -1276,8 +1278,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
       for(i = part, o = enc; *i; i++) {
         if(Curl_isunreserved(*i) ||
            ((*i == '/') && urlskipslash) ||
-           ((*i == '=') && appendquery) ||
+           ((*i == '=') && equalsencode) ||
            ((*i == '+') && plusencode)) {
+          if((*i == '=') && equalsencode)
+            /* only skip the first equals sign */
+            equalsencode = FALSE;
           *o = *i;
           o++;
         }
index 5aa6f4bbc6f7948d18ad6cf5de251ef32f42d4fa..c95401bccd3ee45c96e8a4b56a96d8f11e17c5c4 100644 (file)
@@ -723,7 +723,7 @@ static int get_parts(void)
 static struct querycase append_list[] = {
   {"HTTP://test/?s", "name=joe\x02", "http://test/?s&name=joe%02",
    0, CURLU_URLENCODE, CURLUE_OK},
-  {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe=#f",
+  {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe%3d#f",
    0, CURLU_URLENCODE, CURLUE_OK},
   {"HTTP://test/?size=2#f", "name=joe doe",
    "http://test/?size=2&name=joe+doe#f",