← Commit list

c221469032

Alb3e3
Alb3e3
2026-07-21
SUCCESS Duration: 191s

Subject

urlapi: preserve empty markers in relative URLs

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/urlapi.c+7 -4
@@ -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)
tests/libtest/lib1560.c+15 -8
@@ -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));