]> granicus.if.org Git - mutt/commitdiff
Convert rfc1524_expand_command() implementation to use BUFFER.
authorKevin McCarthy <kevin@8t8.us>
Sun, 14 Apr 2019 20:34:37 +0000 (13:34 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sun, 14 Apr 2019 20:34:37 +0000 (13:34 -0700)
Add mutt_buffer_sanitize_filename() helper.

Add a few end-of-buffer checks while iterating over command.

Convert the parameter name, paramater value, and types to use BUFFER
instead of fixed size strings.

muttlib.c
protos.h
rfc1524.c

index e611bc9894f625e2978be60955bb101fc14fd023..8ab8785fa3a4ba63bb1e9f07da6777310ef64a91 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -1027,6 +1027,24 @@ void mutt_buffer_quote_filename (BUFFER *d, const char *f)
   mutt_buffer_addch (d, '\'');
 }
 
+static const char safe_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+@{}._-:%/";
+
+void mutt_buffer_sanitize_filename (BUFFER *d, const char *f, short slash)
+{
+  mutt_buffer_clear (d);
+
+  if (!f)
+    return;
+
+  for (; *f; f++)
+  {
+    if ((slash && *f == '/') || !strchr (safe_chars, *f))
+      mutt_buffer_addch (d, '_');
+    else
+      mutt_buffer_addch (d, *f);
+  }
+}
+
 void mutt_expand_file_fmt (BUFFER *dest, const char *fmt, const char *src)
 {
   BUFFER *tmp;
index b906e0ccfd5b90c24a679cebd082f08404b6a771..1fd25fb4e2df60aae9182292807d99c9eda8d9f4 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -173,6 +173,7 @@ void mutt_break_thread (HEADER *);
 void mutt_browser_cleanup (void);
 void mutt_buffer_concat_path (BUFFER *, const char *, const char *);
 void mutt_buffer_quote_filename (BUFFER *, const char *);
+void mutt_buffer_sanitize_filename (BUFFER *d, const char *f, short slash);
 void mutt_canonical_charset (char *, size_t, const char *);
 void mutt_check_stats(void);
 int mutt_count_body_parts (CONTEXT *, HEADER *);
index e5b1b85dd00ca7425929f46118ddac686db4f5cc..a7ae9cd2fef194962bd989e28b0a5efe5a2aefa2 100644 (file)
--- a/rfc1524.c
+++ b/rfc1524.c
 #include <errno.h>
 #include <unistd.h>
 
-int mutt_buffer_rfc1524_expand_command (BODY *a, const char *filename, const char *_type,
-                                        BUFFER *command)
-{
-  int rc;
-
-  mutt_buffer_increase_size (command, LONG_STRING);
-  rc = rfc1524_expand_command (a, filename, _type, command->data, command->dsize);
-  mutt_buffer_fix_dptr (command);
-
-  return rc;
-}
-
 /* The command semantics include the following:
  * %s is the filename that contains the mail body data
  * %t is the content type, like text/plain
@@ -67,79 +55,94 @@ int mutt_buffer_rfc1524_expand_command (BODY *a, const char *filename, const cha
  * In addition, this function returns a 0 if the command works on a file,
  * and 1 if the command works on a pipe.
  */
-int rfc1524_expand_command (BODY *a, const char *filename, const char *_type,
-                            char *command, int clen)
+int mutt_buffer_rfc1524_expand_command (BODY *a, const char *filename, const char *_type,
+                                        BUFFER *command)
 {
-  int x=0;
+  const char *cptr;
   int needspipe = TRUE;
   BUFFER *buf = NULL;
   BUFFER *quoted = NULL;
-  char type[LONG_STRING];
+  BUFFER *param = NULL;
+  BUFFER *type = NULL;
 
   buf = mutt_buffer_pool_get ();
   quoted = mutt_buffer_pool_get ();
 
-  strfcpy (type, _type, sizeof (type));
-
-  if (option (OPTMAILCAPSANITIZE))
-    mutt_sanitize_filename (type, 0);
-
-  while (x < clen - 1 && command[x])
+  cptr = mutt_b2s (command);
+  while (*cptr)
   {
-    if (command[x] == '\\')
+    if (*cptr == '\\')
     {
-      x++;
-      mutt_buffer_addch (buf, command[x++]);
+      cptr++;
+      if (*cptr)
+        mutt_buffer_addch (buf, *cptr++);
     }
-    else if (command[x] == '%')
+    else if (*cptr == '%')
     {
-      x++;
-      if (command[x] == '{')
+      cptr++;
+      if (*cptr == '{')
       {
-       char param[STRING];
-       char pvalue[STRING];
-       char *_pvalue;
-       int z = 0;
+       const char *_pvalue;
+
+        if (!param)
+          param = mutt_buffer_pool_get ();
+        else
+          mutt_buffer_clear (param);
 
-       x++;
-       while (command[x] && command[x] != '}' && z < sizeof (param) - 1)
-         param[z++] = command[x++];
-       param[z] = '\0';
+        /* Copy parameter name into param buffer */
+       cptr++;
+       while (*cptr && *cptr != '}')
+          mutt_buffer_addch (param, *cptr++);
 
         /* In send mode, use the current charset, since the message hasn't
          * been converted yet.   If noconv is set, then we assume the
          * charset parameter has the correct value instead. */
-        if ((ascii_strcasecmp (param, "charset") == 0) && a->charset && !a->noconv)
+        if ((ascii_strcasecmp (mutt_b2s (param), "charset") == 0) && a->charset && !a->noconv)
           _pvalue = a->charset;
         else
-          _pvalue = mutt_get_parameter (param, a->parameter);
-       strfcpy (pvalue, NONULL(_pvalue), sizeof (pvalue));
+          _pvalue = mutt_get_parameter (mutt_b2s (param), a->parameter);
+
+        /* Now copy the parameter value into param buffer */
        if (option (OPTMAILCAPSANITIZE))
-         mutt_sanitize_filename (pvalue, 0);
+         mutt_buffer_sanitize_filename (param, NONULL(_pvalue), 0);
+        else
+          mutt_buffer_strcpy (param, NONULL(_pvalue));
 
-       mutt_buffer_quote_filename (quoted, pvalue);
+       mutt_buffer_quote_filename (quoted, mutt_b2s (param));
         mutt_buffer_addstr (buf, mutt_b2s (quoted));
       }
-      else if (command[x] == 's' && filename != NULL)
+      else if (*cptr == 's' && filename != NULL)
       {
        mutt_buffer_quote_filename (quoted, filename);
         mutt_buffer_addstr (buf, mutt_b2s (quoted));
        needspipe = FALSE;
       }
-      else if (command[x] == 't')
+      else if (*cptr == 't')
       {
-       mutt_buffer_quote_filename (quoted, type);
+        if (!type)
+        {
+          type = mutt_buffer_pool_get ();
+          if (option (OPTMAILCAPSANITIZE))
+            mutt_buffer_sanitize_filename (type, _type, 0);
+          else
+            mutt_buffer_strcpy (type, _type);
+        }
+       mutt_buffer_quote_filename (quoted, mutt_b2s (type));
         mutt_buffer_addstr (buf, mutt_b2s (quoted));
       }
-      x++;
+
+      if (*cptr)
+        cptr++;
     }
     else
-      mutt_buffer_addch (buf, command[x++]);
+      mutt_buffer_addch (buf, *cptr++);
   }
-  strfcpy (command, mutt_b2s (buf), clen);
+  mutt_buffer_strcpy (command, mutt_b2s (buf));
 
   mutt_buffer_pool_release (&buf);
   mutt_buffer_pool_release (&quoted);
+  mutt_buffer_pool_release (&param);
+  mutt_buffer_pool_release (&type);
 
   return needspipe;
 }