From 11c14b5ca5cad00a755aacd7bd67a7bd7444902b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Mar 2026 22:36:24 +0100 Subject: [PATCH] urlapi: verify the last letter of a scheme when set explictly A logic error made the function not check the last character, which thus could make it accept invalid schemes. Added test 1965 to verify Reported-by: Otis Cui Lei Closes #20893 --- lib/urlapi.c | 1 + tests/data/Makefile.am | 3 ++- tests/data/test1965 | 44 ++++++++++++++++++++++++++++++ tests/libtest/Makefile.inc | 2 +- tests/libtest/lib1965.c | 55 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 tests/data/test1965 create mode 100644 tests/libtest/lib1965.c diff --git a/lib/urlapi.c b/lib/urlapi.c index a4b82f31bd..e49291f41b 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -1649,6 +1649,7 @@ static CURLUcode set_url_scheme(CURLU *u, const char *scheme, const char *s = scheme; if(ISALPHA(*s)) { /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ + s++; while(--plen) { if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.')) s++; /* fine */ diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 36463204af..1b906a3144 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -239,7 +239,8 @@ test1916 test1917 test1918 test1919 test1920 \ \ test1933 test1934 test1935 test1936 test1937 test1938 test1939 test1940 \ test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \ -test1955 test1956 test1957 test1958 test1959 test1960 test1964 \ +test1955 test1956 test1957 test1958 test1959 test1960 test1964 test1965 \ +\ test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 \ test1978 test1979 test1980 test1981 \ \ diff --git a/tests/data/test1965 b/tests/data/test1965 new file mode 100644 index 0000000000..195ce9c5cf --- /dev/null +++ b/tests/data/test1965 @@ -0,0 +1,44 @@ + + + + +urlapi +curl_url_set + + + + + +curl_url_set() different schemes + + +lib%TESTNUMBER + + + +# Verify data after the test has been "shot" + + +bad! REJECTED +bad{ REJECTED +bad/ REJECTED +bad\ REJECTED +a! REJECTED +a+123 ACCEPTED +http-2 ACCEPTED +http.1 ACCEPTED +a+-.123 ACCEPTED +http-+++2 ACCEPTED +http.1-- ACCEPTED ++a123 REJECTED +-http2 REJECTED +.http1 REJECTED +ABC2 ACCEPTED +2CBA REJECTED + REJECTED +a ACCEPTED +aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd ACCEPTED +aaaaaaaaaabbbbbbbbbbccccccccccdddddddddde REJECTED + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index e3202804a9..d42bdcd07e 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 lib1970.c \ + lib1964.c lib1965.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/lib1965.c b/tests/libtest/lib1965.c new file mode 100644 index 0000000000..fd4207cca2 --- /dev/null +++ b/tests/libtest/lib1965.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * 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_lib1965(const char *URL) +{ + CURLcode result = CURLE_OK; + CURLUcode rc; + const char *schemes[] = { + "bad!", "bad{", "bad/", "bad\\", "a!", + "a+123", "http-2", "http.1", + "a+-.123", "http-+++2", "http.1--", + "+a123", "-http2", ".http1", + "ABC2", "2CBA", "", "a", + "aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd", + "aaaaaaaaaabbbbbbbbbbccccccccccdddddddddde", + NULL}; + int i; + (void) URL; + + global_init(CURL_GLOBAL_ALL); + + for(i = 0; schemes[i]; i++) { + CURLU *url = curl_url(); + rc = curl_url_set(url, CURLUPART_SCHEME, schemes[i], + CURLU_NON_SUPPORT_SCHEME); + curl_mprintf("%s %s\n", schemes[i], + rc == CURLUE_OK ? "ACCEPTED" : "REJECTED"); + curl_url_cleanup(url); + } + + curl_global_cleanup(); + return result; +}