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
This commit is contained in:
Daniel Stenberg 2020-10-15 12:22:27 +02:00
parent 3862c37b63
commit b7ea3d2c22
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 14 additions and 20 deletions

View 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;

View 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,",