ITADN
curl/curl/Issues

URL fragment not getting removed.

#21745Opentiymat 创建于 2026-05-26
T
tiymatcommented
### I did this /tmp/repro.c: ``` #include <stdio.h> #include <curl/curl.h> static const char URL[] = "file:///test?test#test"; int main(void) { CURLU *u = curl_url(); char *out = NULL; CURLUcode rc; rc = curl_url_set(u, CURLUPART_URL, URL, 0); printf("Set url to \"%s\" with rc=%d\n", URL, rc); rc = curl_url_set(u, CURLUPART_URL, "", 0); printf("Set url to empty string with rc=%d\n", rc); rc = curl_url_get(u, CURLUPART_URL, &out, 0); printf("Got url \"%s\" with rc=%d\n", out, rc); curl_free(out); curl_url_cleanup(u); return 0; } ``` ``` > export CURL_PATH="/path/to/curl/repo" > gcc "-I$CURL_PATH/include" /tmp/repro.c "-L$CURL_PATH/lib/.libs" "-Wl,-rpath,$CURL_PATH/lib/.libs" -lcurl -o /tmp/repro && /tmp/repro Set url to "file:///test?test#test" with rc=0 Set url to empty string with rc=0 Got url "file:///test?test#test" with rc=0 ``` ### I expected the following Per 5.2.2 of [RFC3986](https://www.rfc-editor.org/info/rfc3986/#section-5.2.2), my understanding is the output should be `file:///test?test`, with no fragment. The only time the fragment is set in the algorithm in 5.2.2 is right at the end, where `T.fragment = R.fragment;`. In this case, R is `""`, which obviously doesn't have a fragment. The logic causing this is in `set_url` in `lib/urlapi.c` below, where the fragment never gets cleared in the `if(!uc)` branch. ``` if(!part_size) { /* a blank URL is not a valid URL unless we already have a complete one 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 */ curlx_free(oldurl); return CURLUE_OK; } ``` It looks like 15839450be introduced this. The test that commit added uses base `https://example.com` (i.e. a URL without a fragment). This can be fixed by clearing the fragment in the `if(!uc)` branch before returning CURLUE_OK and updating the tests. --- Found due to this WPT URL test case ``` { "input": "", "base": "file:///test?test#test", "href": "file:///test?test", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "?test", "hash": "" } ``` ### curl/libcurl version 230a98663687284eafb80c19f3940f10f4701f12 ### operating system 7.0.9-arch1-1
0 条评论