From: Daniel Stenberg Date: Mon, 5 Jun 2023 06:28:27 +0000 (+0200) Subject: urlapi: scheme starts with alpha X-Git-Tag: curl-8_2_0~157 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba669d072dfd4096a0aef85a7ea4b8f075016297;p=thirdparty%2Fcurl.git urlapi: scheme starts with alpha Add multiple tests to lib1560 to verify Fixes #11249 Reported-by: ad0p on github Closes #11250 --- diff --git a/lib/urlapi.c b/lib/urlapi.c index a4530f919a..07df6d65d8 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -201,7 +201,7 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url, size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen, bool guess_scheme) { - int i; + int i = 0; DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN)); (void)buflen; /* only used in debug-builds */ if(buf) @@ -210,17 +210,18 @@ size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen, if(guess_scheme && STARTS_WITH_DRIVE_PREFIX(url)) return 0; #endif - for(i = 0; i < MAX_SCHEME_LEN; ++i) { - char s = url[i]; - if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) { - /* RFC 3986 3.1 explains: - scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) - */ - } - else { - break; + if(ISALPHA(url[0])) + for(i = 1; i < MAX_SCHEME_LEN; ++i) { + char s = url[i]; + if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) { + /* RFC 3986 3.1 explains: + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ + } + else { + break; + } } - } if(i && (url[i] == ':') && ((url[i + 1] == '/') || !guess_scheme)) { /* If this does not guess scheme, the scheme always ends with the colon so that this also detects data: URLs etc. In guessing mode, data: could @@ -1706,13 +1707,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, return CURLUE_UNSUPPORTED_SCHEME; storep = &u->scheme; urlencode = FALSE; /* never */ - /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ - while(plen--) { - if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.')) - s++; /* fine */ - else - return CURLUE_BAD_SCHEME; + if(ISALPHA(*s)) { + /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ + while(--plen) { + if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.')) + s++; /* fine */ + else + return CURLUE_BAD_SCHEME; + } } + else + return CURLUE_BAD_SCHEME; break; } case CURLUPART_USER: diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c index ee64a1450f..449f937a9d 100644 --- a/tests/libtest/lib1560.c +++ b/tests/libtest/lib1560.c @@ -141,6 +141,22 @@ struct clearurlcase { }; static const struct testcase get_parts_list[] ={ + {"1h://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, + {"..://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, + {"-ht://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, + {"+ftp://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, + {"hej.hej://example.net", + "hej.hej | [11] | [12] | [13] | example.net | [15] | / | [16] | [17]", + CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, + {"ht-tp://example.net", + "ht-tp | [11] | [12] | [13] | example.net | [15] | / | [16] | [17]", + CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, + {"ftp+more://example.net", + "ftp+more | [11] | [12] | [13] | example.net | [15] | / | [16] | [17]", + CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, + {"f1337://example.net", + "f1337 | [11] | [12] | [13] | example.net | [15] | / | [16] | [17]", + CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, {"https://user@example.net?hello# space ", "https | user | [12] | [13] | example.net | [15] | / | hello | %20space%20", CURLU_ALLOW_SPACE|CURLU_URLENCODE, 0, CURLUE_OK}, @@ -733,6 +749,30 @@ static int checkurl(const char *org, const char *url, const char *out) /* !checksrc! disable SPACEBEFORECOMMA 1 */ static const struct setcase set_parts_list[] = { + {"https://example.com/", + "scheme=ftp+-.123,", + "ftp+-.123://example.com/", + 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK}, + {"https://example.com/", + "scheme=1234,", + "https://example.com/", + 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, + {"https://example.com/", + "scheme=1http,", + "https://example.com/", + 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, + {"https://example.com/", + "scheme=-ftp,", + "https://example.com/", + 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, + {"https://example.com/", + "scheme=+ftp,", + "https://example.com/", + 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, + {"https://example.com/", + "scheme=.ftp,", + "https://example.com/", + 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, {"https://example.com/", "host=example.com%2fmoo,", "",