]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ftp: handle the PORT parsing without allocation
authorDaniel Stenberg <daniel@haxx.se>
Tue, 5 Dec 2023 11:15:01 +0000 (12:15 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 7 Dec 2023 07:46:22 +0000 (08:46 +0100)
Also reduces amount of *cpy() calls.

Closes #12456

lib/ftp.c

index a8dcedf531ec9a8e994a069fab1107ef6c01494d..c9ceaaac319c60b68bf6f4b6b3ed84149804b856 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -926,6 +926,8 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
   bool possibly_non_local = TRUE;
   char buffer[STRERROR_LEN];
   char *addr = NULL;
+  size_t addrlen = 0;
+  char ipstr[50];
 
   /* Step 1, figure out what is requested,
    * accepted format :
@@ -934,32 +936,17 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
 
   if(data->set.str[STRING_FTPPORT] &&
      (strlen(data->set.str[STRING_FTPPORT]) > 1)) {
-
-#ifdef ENABLE_IPV6
-    size_t addrlen = INET6_ADDRSTRLEN > strlen(string_ftpport) ?
-      INET6_ADDRSTRLEN : strlen(string_ftpport);
-#else
-    size_t addrlen = INET_ADDRSTRLEN > strlen(string_ftpport) ?
-      INET_ADDRSTRLEN : strlen(string_ftpport);
-#endif
-    char *ip_start = string_ftpport;
     char *ip_end = NULL;
-    char *port_start = NULL;
-    char *port_sep = NULL;
-
-    addr = calloc(1, addrlen + 1);
-    if(!addr) {
-      result = CURLE_OUT_OF_MEMORY;
-      goto out;
-    }
 
 #ifdef ENABLE_IPV6
     if(*string_ftpport == '[') {
       /* [ipv6]:port(-range) */
-      ip_start = string_ftpport + 1;
-      ip_end = strchr(string_ftpport, ']');
-      if(ip_end)
-        strncpy(addr, ip_start, ip_end - ip_start);
+      char *ip_start = string_ftpport + 1;
+      ip_end = strchr(ip_start, ']');
+      if(ip_end) {
+        addrlen = ip_end - ip_start;
+        addr = ip_start;
+      }
     }
     else
 #endif
@@ -969,28 +956,27 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
       }
       else {
         ip_end = strchr(string_ftpport, ':');
+        addr = string_ftpport;
         if(ip_end) {
           /* either ipv6 or (ipv4|domain|interface):port(-range) */
+          addrlen = ip_end - string_ftpport;
 #ifdef ENABLE_IPV6
           if(Curl_inet_pton(AF_INET6, string_ftpport, &sa6->sin6_addr) == 1) {
             /* ipv6 */
             port_min = port_max = 0;
-            strcpy(addr, string_ftpport);
             ip_end = NULL; /* this got no port ! */
           }
-          else
 #endif
-            /* (ipv4|domain|interface):port(-range) */
-            strncpy(addr, string_ftpport, ip_end - ip_start);
         }
         else
           /* ipv4|interface */
-          strcpy(addr, string_ftpport);
+          addrlen = strlen(string_ftpport);
       }
 
     /* parse the port */
     if(ip_end) {
-      port_start = strchr(ip_end, ':');
+      char *port_sep = NULL;
+      char *port_start = strchr(ip_end, ':');
       if(port_start) {
         port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10));
         port_sep = strchr(port_start, '-');
@@ -1011,22 +997,29 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
     if(port_min > port_max)
       port_min = port_max = 0;
 
-    if(*addr != '\0') {
+    if(addrlen) {
+      DEBUGASSERT(addr);
+      if(addrlen >= sizeof(ipstr))
+        goto out;
+      memcpy(ipstr, addr, addrlen);
+      ipstr[addrlen] = 0;
+
       /* attempt to get the address of the given interface name */
       switch(Curl_if2ip(conn->remote_addr->family,
 #ifdef ENABLE_IPV6
                         Curl_ipv6_scope(&conn->remote_addr->sa_addr),
                         conn->scope_id,
 #endif
-                        addr, hbuf, sizeof(hbuf))) {
+                        ipstr, hbuf, sizeof(hbuf))) {
         case IF2IP_NOT_FOUND:
           /* not an interface, use the given string as host name instead */
-          host = addr;
+          host = ipstr;
           break;
         case IF2IP_AF_NOT_SUPPORTED:
           goto out;
         case IF2IP_FOUND:
           host = hbuf; /* use the hbuf for host name */
+          break;
       }
     }
     else
@@ -1266,7 +1259,6 @@ out:
   }
   if(portsock != CURL_SOCKET_BAD)
     Curl_socket_close(data, conn, portsock);
-  free(addr);
   return result;
 }