]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
urlapi: scheme starts with alpha
authorDaniel Stenberg <daniel@haxx.se>
Mon, 5 Jun 2023 06:28:27 +0000 (08:28 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 5 Jun 2023 14:28:27 +0000 (16:28 +0200)
Add multiple tests to lib1560 to verify

Fixes #11249
Reported-by: ad0p on github
Closes #11250

lib/urlapi.c
tests/libtest/lib1560.c

index a4530f919a8ebb8aad7dd47d5907f1540f7eba59..07df6d65d87facb38e9c44d5cb0652fb2ef30c1b 100644 (file)
@@ -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:
index ee64a1450facbdfbe7459485cfddcc8ed6f19f36..449f937a9dd4fa7f4aa67421866b790646a74337 100644 (file)
@@ -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,",
    "",