urlapi: preserve empty markers in relative URLs
No binary (build failed)
—
(log yok)
| @@ -1279,16 +1279,16 @@ static CURLUcode redirect_url(const char *base, const char *relurl, | |
| case '#': | |
| /* fragment-only change */ | |
| - | if(u->fragment) |
| + | if(u->fragment_present) |
| cutoff = strchr(protsep, '#'); | |
| break; | |
| default: | |
| /* path or query-only change */ | |
| - | if(u->query && u->query[0]) |
| + | if(u->query_present) |
| /* remove existing query */ | |
| cutoff = strchr(protsep, '?'); | |
| - | else if(u->fragment && u->fragment[0]) |
| + | else if(u->fragment_present) |
| /* Remove existing fragment */ | |
| cutoff = strchr(protsep, '#'); | |
| @@ -1772,7 +1772,10 @@ static CURLUcode set_url(CURLU *u, const char *url, size_t part_size, | |
| /* if the old URL is incomplete (we cannot get an absolute URL in | |
| 'oldurl'), replace the existing with the new. | |
| Always include "scheme://" to make the URL "complete" */ | |
| - | uc = curl_url_get(u, CURLUPART_URL, &oldurl, flags & ~CURLU_NO_GUESS_SCHEME); |
| + | /* Preserve empty query/fragment separators: they affect where relative |
| + | references splice into the base URL. */ |
| + | uc = curl_url_get(u, CURLUPART_URL, &oldurl, |
| + | (flags & ~CURLU_NO_GUESS_SCHEME) | CURLU_GET_EMPTY); |
| if(uc == CURLUE_OUT_OF_MEMORY) | |
| return uc; | |
| else if(uc) | |
| @@ -1629,19 +1629,26 @@ static const struct redircase set_url_list[] = { | |
| 0, 0, CURLUE_OK}, | |
| {"http://example.org/foo/bar", | |
| "#", | |
| - | "http://example.org/foo/bar", |
| - | /* This happens because the parser removes empty fragments */ |
| + | "http://example.org/foo/bar#", |
| 0, 0, CURLUE_OK}, | |
| {"http://example.org/foo/bar", | |
| "?", | |
| - | "http://example.org/foo/bar", |
| - | /* This happens because the parser removes empty queries */ |
| + | "http://example.org/foo/bar?", |
| 0, 0, CURLUE_OK}, | |
| {"http://example.org/foo/bar", | |
| "?#", | |
| - | "http://example.org/foo/bar", |
| - | /* This happens because the parser removes empty queries and fragments */ |
| - | 0, 0, CURLUE_OK}, |
| + | "http://example.org/foo/bar?#", |
| + | 0, 0, CURLUE_OK}, |
| + | {"http://host/path?", "#new", |
| + | "http://host/path?#new", 0, 0, CURLUE_OK}, |
| + | {"http://host/path?#", "#new", |
| + | "http://host/path?#new", 0, 0, CURLUE_OK}, |
| + | {"http://host/path#", "?new", |
| + | "http://host/path?new", 0, 0, CURLUE_OK}, |
| + | {"http://host/path?#", "?new", |
| + | "http://host/path?new", 0, 0, CURLUE_OK}, |
| + | {"http://host/path?#", "sub", |
| + | "http://host/sub", 0, 0, CURLUE_OK}, |
| {"http://example.com/please/../gimme/%TESTNUMBER?foobar#hello", | |
| "http://example.net/there/it/is/../../tes t case=/%TESTNUMBER0002? yes no", | |
| "http://example.net/there/tes%20t%20case=/%TESTNUMBER0002?+yes+no", | |
| @@ -1716,7 +1723,7 @@ static int set_url(void) | |
| } | |
| else { | |
| char *url = NULL; | |
| - | rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); |
| + | rc = curl_url_get(urlp, CURLUPART_URL, &url, CURLU_GET_EMPTY); |
| if(rc) { | |
| curl_mfprintf(stderr, "%s:%d Get URL returned %d (%s)\n", | |
| __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | |