From c8d23451ccebf98b16dccb1869a38728c4098f50 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 15 Oct 2020 12:22:27 +0200 Subject: urlapi: URL encode a '+' in the query part ... when asked to with URL CURLU_URLENCODE. Extended test 1560 to verify. Reported-by: Dietmar Hauser Fixes #6086 --- lib/urlapi.c | 27 +++++++-------------------- tests/libtest/lib1560.c | 7 +++++++ 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 @@ -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,", -- cgit v1.2.1