diff --git a/lib/urlapi.c b/lib/urlapi.c index 1ec87859dd..1aab7f9418 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -965,22 +965,30 @@ static CURLUcode parse_scheme(const char *url, CURLU *u, char *schemebuf, const char *schemep = NULL; if(schemelen) { - int i = 0; + int num_slashes = 0; const char *p = &url[schemelen + 1]; - while((*p == '/') && (i < 4)) { - p++; - i++; + if(!Curl_get_scheme(schemebuf) && !(flags & CURLU_NON_SUPPORT_SCHEME)) + return CURLUE_UNSUPPORTED_SCHEME; + + if(!ISSLASH(*p)) + /* less than one */ + return CURLUE_BAD_SLASHES; + if((flags & CURLU_NO_AUTHORITY)) { + while(ISSLASH(*p) && (num_slashes < 2)) { + p++; + num_slashes++; + } + } + else { + while(ISSLASH(*p) && (num_slashes < 4)) { + p++; + num_slashes++; + } + if(num_slashes > 3) + return CURLUE_BAD_SLASHES; } schemep = schemebuf; - if(!Curl_get_scheme(schemep) && - !(flags & CURLU_NON_SUPPORT_SCHEME)) - return CURLUE_UNSUPPORTED_SCHEME; - - if((i < 1) || (i > 3)) - /* less than one or more than three slashes */ - return CURLUE_BAD_SLASHES; - *hostpp = p; /* hostname starts here */ } else { diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c index 5eda0bc6dc..9c8f0e2b35 100644 --- a/tests/libtest/lib1560.c +++ b/tests/libtest/lib1560.c @@ -153,6 +153,16 @@ struct clearurlcase { }; static const struct testcase get_parts_list[] = { + /* non-supported URL without hostname */ + {"weird:///path", + "weird | [11] | [12] | [13] | | [15] | /path | [16] | [17]", + CURLU_NON_SUPPORT_SCHEME|CURLU_NO_AUTHORITY, 0, CURLUE_OK}, + /* non-supported URL without hostname, using path with multiple leading + slashes */ + {"weird:////path", + "weird | [11] | [12] | [13] | | [15] | //path | [16] | [17]", + CURLU_NON_SUPPORT_SCHEME|CURLU_NO_AUTHORITY, 0, CURLUE_OK}, + /* RFC 4291 IPv4-Mapped IPv6 Addresses */ {"https://[0:0:0:0:0:FFFF:129.144.52.38]:1234", "https | [11] | [12] | [13] | [::ffff:129.144.52.38] | 1234 "