Просмотр исходного кода

curl: Backport upstream curl fixes for no_proxy to CMake 3.25 release

CMake 3.25 updated to curl 7.86, which had some `no_proxy` regressions.
Backport upstream curl fixes:

* commit `b830f9ba9` (noproxy: fix tail-matching)
* commit `b1953c193` (noproxy: tailmatch like in 7.85.0 and earlier)
* commit `60453483b` (noproxy: guard against empty hostnames)

CMake 3.26 already updated to curl 7.87, and has the fixes.

Fixes: #24426
Brad King 2 лет назад
Родитель
Сommit
ccdc358f49
1 измененных файлов с 35 добавлено и 10 удалено
  1. 35 10
      Utilities/cmcurl/lib/noproxy.c

+ 35 - 10
Utilities/cmcurl/lib/noproxy.c

@@ -117,6 +117,13 @@ enum nametype {
 ****************************************************************/
 bool Curl_check_noproxy(const char *name, const char *no_proxy)
 {
+  /*
+   * If we don't have a hostname at all, like for example with a FILE
+   * transfer, we have nothing to interrogate the noproxy list with.
+   */
+  if(!name || name[0] == '\0')
+    return FALSE;
+
   /* no_proxy=domain1.dom,host.domain2.dom
    *   (a comma-separated list of hosts which should
    *   not be proxied, or an asterisk to override
@@ -149,9 +156,14 @@ bool Curl_check_noproxy(const char *name, const char *no_proxy)
     }
     else {
       unsigned int address;
+      namelen = strlen(name);
       if(1 == Curl_inet_pton(AF_INET, name, &address))
         type = TYPE_IPV4;
-      namelen = strlen(name);
+      else {
+        /* ignore trailing dots in the host name */
+        if(name[namelen - 1] == '.')
+          namelen--;
+      }
     }
 
     while(*p) {
@@ -173,16 +185,29 @@ bool Curl_check_noproxy(const char *name, const char *no_proxy)
       if(tokenlen) {
         switch(type) {
         case TYPE_HOST:
-          if(*token == '.') {
-            ++token;
-            --tokenlen;
-            /* tailmatch */
-            match = (tokenlen <= namelen) &&
-              strncasecompare(token, name + (namelen - tokenlen), namelen);
+          /* ignore trailing dots in the token to check */
+          if(token[tokenlen - 1] == '.')
+            tokenlen--;
+
+          if(tokenlen && (*token == '.')) {
+            /* ignore leading token dot as well */
+            token++;
+            tokenlen--;
           }
-          else
-            match = (tokenlen == namelen) &&
-              strncasecompare(token, name, namelen);
+          /* A: example.com matches 'example.com'
+             B: www.example.com matches 'example.com'
+             C: nonexample.com DOES NOT match 'example.com'
+          */
+          if(tokenlen == namelen)
+            /* case A, exact match */
+            match = strncasecompare(token, name, namelen);
+          else if(tokenlen < namelen) {
+            /* case B, tailmatch domain */
+            match = (name[namelen - tokenlen - 1] == '.') &&
+              strncasecompare(token, name + (namelen - tokenlen),
+                              tokenlen);
+          }
+          /* case C passes through, not a match */
           break;
         case TYPE_IPV4:
           /* FALLTHROUGH */