]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tool_formparse: simplify get_param_part
authorDaniel Stenberg <daniel@haxx.se>
Thu, 30 Apr 2026 12:51:47 +0000 (14:51 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 1 May 2026 08:26:33 +0000 (10:26 +0200)
Introduce a few sub functions to reduce complexity

Closes #21478

src/tool_formparse.c

index e129452d4362c2a36ba1a51b13385b4f909f131b..67e73fc47926b57f145ce63fd3bbab426f999d39 100644 (file)
@@ -472,6 +472,137 @@ static int read_field_headers(FILE *fp, struct curl_slist **pheaders)
   return err;
 }
 
+static void param_type(char **ptr, char **ptype, char **endct, char *sep)
+{
+  char *p = *ptr;
+  size_t tlen;
+  for(p += sizeof("type=") - 1; ISBLANK(*p); p++)
+    ;
+  /* set type pointer */
+  *ptype = p;
+
+  /* find end of content-type */
+  tlen = strcspn(p, "()<>@,;:\\\"[]?=\r\n ");
+  p += tlen;
+  *endct = p;
+  *sep = *p;
+  *ptr = p;
+}
+
+static void param_filename(char **ptr, char **endct, char **pfilename,
+                           char endchar, char *sep)
+{
+  char *p = *ptr;
+  char *endpos;
+  char *tp;
+
+  if(*endct) {
+    **endct = '\0';
+    *endct = NULL;
+  }
+  for(p += sizeof("filename=") - 1; ISBLANK(*p); p++)
+    ;
+  tp = p;
+  *pfilename = get_param_word(&p, &endpos, endchar);
+  /* If not quoted, strip trailing spaces. */
+  if(*pfilename == tp)
+    while(endpos > *pfilename && ISBLANK(endpos[-1]))
+      endpos--;
+  *sep = *p;
+  *endpos = '\0';
+  *ptr = p;
+}
+
+static int param_headers(char **ptr, char **endct,
+                         struct curl_slist **pheaders, char endchar, char *sep)
+{
+  char *p = *ptr;
+  char *endpos;
+  char *tp;
+
+  if(*endct) {
+    **endct = '\0';
+    *endct = NULL;
+  }
+  p += sizeof("headers=") - 1;
+  if(*p == '@' || *p == '<') {
+    char *hdrfile;
+    FILE *fp;
+    /* Read headers from a file. */
+    do {
+      p++;
+    } while(ISBLANK(*p));
+    tp = p;
+    hdrfile = get_param_word(&p, &endpos, endchar);
+    /* If not quoted, strip trailing spaces. */
+    if(hdrfile == tp)
+      while(endpos > hdrfile && ISBLANK(endpos[-1]))
+        endpos--;
+    *sep = *p;
+    *endpos = '\0';
+    fp = curlx_fopen(hdrfile, FOPEN_READTEXT);
+    if(!fp) {
+      char errbuf[STRERROR_LEN];
+      warnf("Cannot read from %s: %s", hdrfile,
+            curlx_strerror(errno, errbuf, sizeof(errbuf)));
+    }
+    else {
+      int i = read_field_headers(fp, pheaders);
+
+      curlx_fclose(fp);
+      if(i) {
+        curl_slist_free_all(*pheaders);
+        return -1;
+      }
+    }
+  }
+  else {
+    char *hdr;
+
+    while(ISBLANK(*p))
+      p++;
+    tp = p;
+    hdr = get_param_word(&p, &endpos, endchar);
+    /* If not quoted, strip trailing spaces. */
+    if(hdr == tp)
+      while(endpos > hdr && ISBLANK(endpos[-1]))
+        endpos--;
+    *sep = *p;
+    *endpos = '\0';
+    if(slist_append(pheaders, hdr)) {
+      errorf("Out of memory for field header");
+      curl_slist_free_all(*pheaders);
+      return -1;
+    }
+  }
+  *ptr = p;
+  return 0;
+}
+
+static void param_encoder(char **ptr, char **endct, char **pencoder,
+                          char endchar, char *sep)
+{
+  char *p = *ptr;
+  char *endpos;
+  char *tp;
+
+  if(*endct) {
+    **endct = '\0';
+    *endct = NULL;
+  }
+  for(p += sizeof("encoder=") - 1; ISBLANK(*p); p++)
+    ;
+  tp = p;
+  *pencoder = get_param_word(&p, &endpos, endchar);
+  /* If not quoted, strip trailing spaces. */
+  if(*pencoder == tp)
+    while(endpos > *pencoder && ISSPACE(endpos[-1]))
+      endpos--;
+  *sep = *p;
+  *endpos = '\0';
+  *ptr = p;
+}
+
 static int get_param_part(char endchar,
                           char **str, char **pdata, char **ptype,
                           char **pfilename, char **pencoder,
@@ -509,108 +640,16 @@ static int get_param_part(char endchar,
     while(p++ && ISBLANK(*p))
       ;
 
-    if(!endct && checkprefix("type=", p)) {
-      size_t tlen;
-      for(p += 5; ISBLANK(*p); p++)
-        ;
-      /* set type pointer */
-      type = p;
-
-      /* find end of content-type */
-      tlen = strcspn(p, "()<>@,;:\\\"[]?=\r\n ");
-      p += tlen;
-      endct = p;
-      sep = *p;
-    }
-    else if(checkprefix("filename=", p)) {
-      if(endct) {
-        *endct = '\0';
-        endct = NULL;
-      }
-      for(p += 9; ISBLANK(*p); p++)
-        ;
-      tp = p;
-      filename = get_param_word(&p, &endpos, endchar);
-      /* If not quoted, strip trailing spaces. */
-      if(filename == tp)
-        while(endpos > filename && ISBLANK(endpos[-1]))
-          endpos--;
-      sep = *p;
-      *endpos = '\0';
-    }
+    if(!endct && checkprefix("type=", p))
+      param_type(&p, &type, &endct, &sep);
+    else if(checkprefix("filename=", p))
+      param_filename(&p, &endct, &filename, endchar, &sep);
     else if(checkprefix("headers=", p)) {
-      if(endct) {
-        *endct = '\0';
-        endct = NULL;
-      }
-      p += 8;
-      if(*p == '@' || *p == '<') {
-        char *hdrfile;
-        FILE *fp;
-        /* Read headers from a file. */
-        do {
-          p++;
-        } while(ISBLANK(*p));
-        tp = p;
-        hdrfile = get_param_word(&p, &endpos, endchar);
-        /* If not quoted, strip trailing spaces. */
-        if(hdrfile == tp)
-          while(endpos > hdrfile && ISBLANK(endpos[-1]))
-            endpos--;
-        sep = *p;
-        *endpos = '\0';
-        fp = curlx_fopen(hdrfile, FOPEN_READTEXT);
-        if(!fp) {
-          char errbuf[STRERROR_LEN];
-          warnf("Cannot read from %s: %s", hdrfile,
-                curlx_strerror(errno, errbuf, sizeof(errbuf)));
-        }
-        else {
-          int i = read_field_headers(fp, &headers);
-
-          curlx_fclose(fp);
-          if(i) {
-            curl_slist_free_all(headers);
-            return -1;
-          }
-        }
-      }
-      else {
-        char *hdr;
-
-        while(ISBLANK(*p))
-          p++;
-        tp = p;
-        hdr = get_param_word(&p, &endpos, endchar);
-        /* If not quoted, strip trailing spaces. */
-        if(hdr == tp)
-          while(endpos > hdr && ISBLANK(endpos[-1]))
-            endpos--;
-        sep = *p;
-        *endpos = '\0';
-        if(slist_append(&headers, hdr)) {
-          errorf("Out of memory for field header");
-          curl_slist_free_all(headers);
-          return -1;
-        }
-      }
-    }
-    else if(checkprefix("encoder=", p)) {
-      if(endct) {
-        *endct = '\0';
-        endct = NULL;
-      }
-      for(p += 8; ISBLANK(*p); p++)
-        ;
-      tp = p;
-      encoder = get_param_word(&p, &endpos, endchar);
-      /* If not quoted, strip trailing spaces. */
-      if(encoder == tp)
-        while(endpos > encoder && ISSPACE(endpos[-1]))
-          endpos--;
-      sep = *p;
-      *endpos = '\0';
+      if(param_headers(&p, &endct, &headers, endchar, &sep))
+        return -1;
     }
+    else if(checkprefix("encoder=", p))
+      param_encoder(&p, &endct, &encoder, endchar, &sep);
     else if(endct) {
       /* This is part of content type. */
       for(endct = p; *p && *p != ';' && *p != endchar; p++)