From 7e350dd147ff64aead4595c3658c1f60e2dc749f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 21 May 2026 23:00:55 +0200 Subject: [PATCH] urlapi: fix redirect handling if CURLU_NO_GUESS_SCHEME is set Verified by test 1967 Reported-by: Joshua Rogers Closes #21721 --- lib/urlapi.c | 5 +++-- tests/data/Makefile.am | 2 +- tests/data/test1967 | 30 +++++++++++++++++++++++++++ tests/libtest/Makefile.inc | 2 +- tests/libtest/lib1967.c | 42 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 tests/data/test1967 create mode 100644 tests/libtest/lib1967.c diff --git a/lib/urlapi.c b/lib/urlapi.c index 21f4bbfab1..ef5b2b48e9 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -1731,8 +1731,9 @@ static CURLUcode set_url(CURLU *u, const char *url, size_t part_size, return parseurl_and_replace(url, u, flags); /* if the old URL is incomplete (we cannot get an absolute URL in - 'oldurl'), replace the existing with the new */ - uc = curl_url_get(u, CURLUPART_URL, &oldurl, flags); + '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); if(uc == CURLUE_OUT_OF_MEMORY) return uc; else if(uc) diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 2621c4dc7b..08b2f17dd0 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -239,7 +239,7 @@ test1916 test1917 test1918 test1919 test1920 test1921 \ test1933 test1934 test1935 test1936 test1937 test1938 test1939 test1940 \ test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \ test1955 test1956 test1957 test1958 test1959 test1960 test1964 test1965 \ -test1966 \ +test1966 test1967 \ \ test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 \ test1978 test1979 test1980 test1981 test1982 test1983 test1984 \ diff --git a/tests/data/test1967 b/tests/data/test1967 new file mode 100644 index 0000000000..c012a70ba6 --- /dev/null +++ b/tests/data/test1967 @@ -0,0 +1,30 @@ + + + + +HTTP +urlapi + + + + + + +curl_url_set() a URL without guessing a scheme + + +lib%TESTNUMBER + + + +http://%HOSTIP:%NOLISTENPORT/not-there/%TESTNUMBER + + + +# Verify data after the test has been "shot" + + +URL http://a.b/x + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index d3e194b0c7..ad86411a7f 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -108,7 +108,7 @@ TESTS_C = \ lib1940.c lib1945.c \ lib1947.c lib1948.c \ lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c \ - lib1964.c lib1965.c lib1970.c \ + lib1964.c lib1965.c lib1967.c lib1970.c \ lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c \ lib2023.c lib2032.c lib2082.c \ lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c \ diff --git a/tests/libtest/lib1967.c b/tests/libtest/lib1967.c new file mode 100644 index 0000000000..e271df28d9 --- /dev/null +++ b/tests/libtest/lib1967.c @@ -0,0 +1,42 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "first.h" + +static CURLcode test_lib1967(const char *URL) +{ + CURLU *u = curl_url(); + (void)URL; + if(u) { + char *url; + curl_url_set(u, CURLUPART_URL, "a.b", CURLU_GUESS_SCHEME); + curl_url_set(u, CURLUPART_URL, "/x", CURLU_NO_GUESS_SCHEME); + + if(!curl_url_get(u, CURLUPART_URL, &url, 0)) { + curl_mprintf("URL %s\n", url); + curl_free(url); + } + curl_url_cleanup(u); + } + return CURLE_OK; +}