From 9aa8ff2895df60f2857d26fb3262c231511114a9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 6 Nov 2018 23:48:35 +0100 Subject: [PATCH] urlapi: only skip encoding the first '=' with APPENDQUERY set 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 | 11 ++++++----- lib/urlapi.c | 7 ++++++- tests/libtest/lib1560.c | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/libcurl/curl_url_set.3 b/docs/libcurl/curl_url_set.3 index 4ecfcafa0..4c8ff9810 100644 --- a/docs/libcurl/curl_url_set.3 +++ b/docs/libcurl/curl_url_set.3 @@ -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 diff --git a/lib/urlapi.c b/lib/urlapi.c index e877dc726..2830dc163 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -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++; } diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c index 5aa6f4bbc..c95401bcc 100644 --- a/tests/libtest/lib1560.c +++ b/tests/libtest/lib1560.c @@ -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",