mirror of
https://github.com/curl/curl.git
synced 2026-06-07 11:34:15 +03:00
urlapi: allow more path characters "raw" when asked to URL encode
Setting the path component to contain the letters:
! $ & ' ( ) { } [ ] * + , ; = : @
now leaves them un-encoded when CURLU_URLENCODE is used.
Amended test 1560 to verify.
Reported-by: Jeroen Ooms
Fixes #17977
This commit is contained in:
parent
1055144063
commit
768c0f0779
3 changed files with 24 additions and 5 deletions
|
|
@ -184,8 +184,10 @@ course cannot know if the provided scheme is a valid one or not.
|
|||
When set, curl_url_set(3) URL encodes the part on entry, except for
|
||||
**scheme**, **port** and **URL**.
|
||||
|
||||
When setting the path component with URL encoding enabled, the slash character
|
||||
is skipped.
|
||||
When setting the path component with URL encoding enabled, the following
|
||||
characters are left as-is if present:
|
||||
|
||||
! $ & ' ( ) { } [ ] * + , ; = : @
|
||||
|
||||
The query part gets space-to-plus converted before the URL conversion is
|
||||
applied.
|
||||
|
|
|
|||
19
lib/urlapi.c
19
lib/urlapi.c
|
|
@ -1757,13 +1757,26 @@ static CURLUcode urlset_clear(CURLU *u, CURLUPart what)
|
|||
return CURLUE_OK;
|
||||
}
|
||||
|
||||
static bool allowed_in_path(unsigned char x)
|
||||
{
|
||||
switch(x) {
|
||||
case '!': case '$': case '&': case '\'':
|
||||
case '(': case ')': case '{': case '}':
|
||||
case '[': case ']': case '*': case '+':
|
||||
case ',': case ';': case '=': case ':':
|
||||
case '@': case '/':
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CURLUcode curl_url_set(CURLU *u, CURLUPart what,
|
||||
const char *part, unsigned int flags)
|
||||
{
|
||||
char **storep = NULL;
|
||||
bool urlencode = (flags & CURLU_URLENCODE) ? 1 : 0;
|
||||
bool plusencode = FALSE;
|
||||
bool urlskipslash = FALSE;
|
||||
bool pathmode = FALSE;
|
||||
bool leadingslash = FALSE;
|
||||
bool appendquery = FALSE;
|
||||
bool equalsencode = FALSE;
|
||||
|
|
@ -1808,7 +1821,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
|
|||
case CURLUPART_PORT:
|
||||
return set_url_port(u, part);
|
||||
case CURLUPART_PATH:
|
||||
urlskipslash = TRUE;
|
||||
pathmode = TRUE;
|
||||
leadingslash = TRUE; /* enforce */
|
||||
storep = &u->path;
|
||||
break;
|
||||
|
|
@ -1850,7 +1863,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
|
|||
return CURLUE_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(ISUNRESERVED(*i) ||
|
||||
((*i == '/') && urlskipslash) ||
|
||||
(pathmode && allowed_in_path(*i)) ||
|
||||
((*i == '=') && equalsencode)) {
|
||||
if((*i == '=') && equalsencode)
|
||||
/* only skip the first equals sign */
|
||||
|
|
|
|||
|
|
@ -895,6 +895,10 @@ static const struct setgetcase setget_parts_list[] = {
|
|||
|
||||
/* !checksrc! disable SPACEBEFORECOMMA 1 */
|
||||
static const struct setcase set_parts_list[] = {
|
||||
{"https://example.com/",
|
||||
"path=one /$!$&'()*+;=:@{}[]%,",
|
||||
"https://example.com/one%20/$!$&'()*+;=:@{}[]%25",
|
||||
0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
|
||||
{NULL, /* start fresh! */
|
||||
"scheme=https,path=/,url=\"\",", /* incomplete url, redirect to "" */
|
||||
"https://example.com/",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue