]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
imap: use a dynbuf in imap_atom
authorDaniel Stenberg <daniel@haxx.se>
Mon, 14 Aug 2023 09:41:03 +0000 (11:41 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 14 Aug 2023 13:56:11 +0000 (15:56 +0200)
Avoid a calculation + malloc. Build the output in a dynbuf.

Closes #11672

lib/imap.c

index 57ab504a6f8569510d734bc4cf623f02a2462d8c..27b7ac94c314e00aac8bab63511b0f3d7b192716 100644 (file)
@@ -1803,79 +1803,37 @@ static CURLcode imap_sendf(struct Curl_easy *data, const char *fmt, ...)
  */
 static char *imap_atom(const char *str, bool escape_only)
 {
-  /* !checksrc! disable PARENBRACE 1 */
-  const char atom_specials[] = "(){ %*]";
-  const char *p1;
-  char *p2;
-  size_t backsp_count = 0;
-  size_t quote_count = 0;
-  bool others_exists = FALSE;
-  size_t newlen = 0;
-  char *newstr = NULL;
+  struct dynbuf line;
+  size_t nclean;
+  size_t len;
 
   if(!str)
     return NULL;
 
-  /* Look for "atom-specials", counting the backslash and quote characters as
-     these will need escaping */
-  p1 = str;
-  while(*p1) {
-    if(*p1 == '\\')
-      backsp_count++;
-    else if(*p1 == '"')
-      quote_count++;
-    else if(!escape_only) {
-      const char *p3 = atom_specials;
-
-      while(*p3 && !others_exists) {
-        if(*p1 == *p3)
-          others_exists = TRUE;
-
-        p3++;
-      }
-    }
-
-    p1++;
-  }
-
-  /* Does the input contain any "atom-special" characters? */
-  if(!backsp_count && !quote_count && !others_exists)
+  len = strlen(str);
+  nclean = strcspn(str, "() {%*]\\\"");
+  if(len == nclean)
+    /* nothing to escape, return a strdup */
     return strdup(str);
 
-  /* Calculate the new string length */
-  newlen = strlen(str) + backsp_count + quote_count + (escape_only ? 0 : 2);
+  Curl_dyn_init(&line, 2000);
 
-  /* Allocate the new string */
-  newstr = (char *) malloc((newlen + 1) * sizeof(char));
-  if(!newstr)
+  if(!escape_only && Curl_dyn_addn(&line, "\"", 1))
     return NULL;
 
-  /* Surround the string in quotes if necessary */
-  p2 = newstr;
-  if(!escape_only) {
-    newstr[0] = '"';
-    newstr[newlen - 1] = '"';
-    p2++;
+  while(*str) {
+    if((*str == '\\' || *str == '"') &&
+       Curl_dyn_addn(&line, "\\", 1))
+      return NULL;
+    if(Curl_dyn_addn(&line, str, 1))
+      return NULL;
+    str++;
   }
 
-  /* Copy the string, escaping backslash and quote characters along the way */
-  p1 = str;
-  while(*p1) {
-    if(*p1 == '\\' || *p1 == '"') {
-      *p2 = '\\';
-      p2++;
-    }
-
-   *p2 = *p1;
-
-    p1++;
-    p2++;
-  }
-
-  /* Terminate the string */
-  newstr[newlen] = '\0';
+  if(!escape_only && Curl_dyn_addn(&line, "\"", 1))
+    return NULL;
 
-  return newstr;
+  return Curl_dyn_ptr(&line);
 }
 
 /***********************************************************************