]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
altsvc: make it one malloc instead of three per entry
authorDaniel Stenberg <daniel@haxx.se>
Sat, 6 Dec 2025 17:01:09 +0000 (18:01 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 6 Dec 2025 22:50:58 +0000 (23:50 +0100)
Also return OOM correctly.

Closes #19857

lib/altsvc.c
lib/setopt.c

index f2906ad4e3799a90fde531654f28808458c5e3b6..31f6b515bec24187475945aa75b340679df1a05a 100644 (file)
@@ -64,12 +64,7 @@ const char *Curl_alpnid2str(enum alpnid id)
   }
 }
 
-static void altsvc_free(struct altsvc *as)
-{
-  curlx_free(as->src.host);
-  curlx_free(as->dst.host);
-  curlx_free(as);
-}
+#define altsvc_free(x) curlx_free(x)
 
 static struct altsvc *altsvc_createid(const char *srchost,
                                       size_t hlen,
@@ -80,38 +75,35 @@ static struct altsvc *altsvc_createid(const char *srchost,
                                       size_t srcport,
                                       size_t dstport)
 {
-  struct altsvc *as = curlx_calloc(1, sizeof(struct altsvc));
-  if(!as)
-    return NULL;
-  DEBUGASSERT(hlen);
-  DEBUGASSERT(dlen);
-  if(!hlen || !dlen)
-    /* bad input */
-    goto error;
+  struct altsvc *as;
   if((hlen > 2) && srchost[0] == '[') {
     /* IPv6 address, strip off brackets */
     srchost++;
     hlen -= 2;
   }
-  else if(srchost[hlen - 1] == '.') {
+  else if(hlen && (srchost[hlen - 1] == '.')) {
     /* strip off trailing dot */
     hlen--;
-    if(!hlen)
-      goto error;
   }
   if((dlen > 2) && dsthost[0] == '[') {
     /* IPv6 address, strip off brackets */
     dsthost++;
     dlen -= 2;
   }
+  if(!hlen || !dlen)
+    /* bad input */
+    return NULL;
+  /* struct size plus both strings */
+  as = curlx_calloc(1, sizeof(struct altsvc) + (hlen + 1) + (dlen + 1));
+  if(!as)
+    return NULL;
+  as->src.host = (char *)as + sizeof(struct altsvc);
+  memcpy(as->src.host, srchost, hlen);
+  /* the null terminator is already there */
 
-  as->src.host = Curl_memdup0(srchost, hlen);
-  if(!as->src.host)
-    goto error;
-
-  as->dst.host = Curl_memdup0(dsthost, dlen);
-  if(!as->dst.host)
-    goto error;
+  as->dst.host = (char *)as + sizeof(struct altsvc) + hlen + 1;
+  memcpy(as->dst.host, dsthost, dlen);
+  /* the null terminator is already there */
 
   as->src.alpnid = srcalpnid;
   as->dst.alpnid = dstalpnid;
@@ -119,9 +111,6 @@ static struct altsvc *altsvc_createid(const char *srchost,
   as->dst.port = (unsigned short)dstport;
 
   return as;
-error:
-  altsvc_free(as);
-  return NULL;
 }
 
 static struct altsvc *altsvc_create(struct Curl_str *srchost,
@@ -194,6 +183,8 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, const char *line)
       as->persist = persist ? 1 : 0;
       Curl_llist_append(&asi->list, as, &as->node);
     }
+    else
+      return CURLE_OUT_OF_MEMORY;
   }
 
   return CURLE_OK;
@@ -600,6 +591,8 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
                   (int)curlx_strlen(&dsthost), curlx_str(&dsthost),
                   dstport, Curl_alpnid2str(dstalpnid));
           }
+          else
+            return CURLE_OUT_OF_MEMORY;
         }
       }
       else
index 476506dad4dca13085acf46e0d3985bbf2f0cf66..24d8fe8de060d1557edc8dffb00e500ab52f81c9 100644 (file)
@@ -2532,7 +2532,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option,
     if(result)
       return result;
     if(ptr)
-      (void)Curl_altsvc_load(data->asi, ptr);
+      return Curl_altsvc_load(data->asi, ptr);
     break;
 #endif /* ! CURL_DISABLE_ALTSVC */
 #ifdef USE_ECH