From 780ccb256e0dcea71b4e5758da4df997a526c06f Mon Sep 17 00:00:00 2001 From: tiymat <138939221+tiymat@users.noreply.github.com> Date: Tue, 26 May 2026 23:32:32 -0230 Subject: [PATCH] urlapi: drop base fragment on empty redirect Extended test 1560 to verify Fixes #21745 Closes #21763 --- lib/urlapi.c | 7 +++++-- tests/data/test1560 | 2 +- tests/libtest/lib1560.c | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/lib/urlapi.c b/lib/urlapi.c index a5ec95032b..d92887bf88 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -1721,8 +1721,11 @@ static CURLUcode set_url(CURLU *u, const char *url, size_t part_size, and this is a redirect */ uc = curl_url_get(u, CURLUPART_URL, &oldurl, flags); if(!uc) { - /* success, meaning the "" is a fine relative URL, but nothing - changes */ + /* success, meaning the "" is a fine relative URL, and the new URL + inherits scheme/authority/path/query, but not fragment, from the + existing URL (RFC 3986 section 5.2.2) */ + curlx_safefree(u->fragment); + u->fragment_present = FALSE; curlx_free(oldurl); return CURLUE_OK; } diff --git a/tests/data/test1560 b/tests/data/test1560 index e27229739f..7f78aece2f 100644 --- a/tests/data/test1560 +++ b/tests/data/test1560 @@ -37,7 +37,7 @@ lib%TESTNUMBER success -Allocations: 3200 +Allocations: 3250 diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c index bdf8b56cad..a62d9334b2 100644 --- a/tests/libtest/lib1560.c +++ b/tests/libtest/lib1560.c @@ -1356,6 +1356,33 @@ static const struct redircase set_url_list[] = { "", /* blank redirect */ "https://example.com/", 0, 0, CURLUE_OK }, + {"file:///test?test#test", + "", "file:///test?test", + 0, 0, CURLUE_OK}, + {"https://example.com/path?query#frag", + "", "https://example.com/path?query", + 0, 0, CURLUE_OK}, + {"ftp://example.com/dir/file#anchor", + "", "ftp://example.com/dir/file", + 0, 0, CURLUE_OK}, + {"http://example.com/path#frag", + "", "http://example.com/path", + 0, 0, CURLUE_OK}, + {"http://example.com/#frag", + "", "http://example.com/", + 0, 0, CURLUE_OK}, + {"http://user:pass@example.com/path?query#frag", + "", "http://user:pass@example.com/path?query", + 0, 0, CURLUE_OK}, + {"http://example.com:8080/path?query#frag", + "", "http://example.com:8080/path?query", + 0, 0, CURLUE_OK}, + {"https://user:pass@example.com:8443/path?query#frag", + "", "https://user:pass@example.com:8443/path?query", + 0, 0, CURLUE_OK}, + {"http://[::1]/path#frag", + "", "http://[::1]/path", + 0, 0, CURLUE_OK}, {"http://firstplace.example.com/want/1314", "//somewhere.example.com/reply/1314", "http://somewhere.example.com/reply/1314",