<<< Date Index >>>     <<< Thread Index >>>

[PATCH] attach filenames with whitespace embedded



On 2006-01-15 at 22:41 +0100, Thomas Roessler wrote:
> Well, you can actually put an "Attach" pseudoheader into your
> message while you compose it, if you have header editing turned
> on.  Mutt will attach the file that's identified there.

Neat!

But I deal with too many documents at work which are named with embedded
whitespace.  :^(

The attached patch is a first stab at dealing with this, by allowing the
filename to be quoted.

However, despite handling embedded quotes (keep looking past a
double-quotes if the previous character was a backslash) it doesn't do
any backslash de-escaping, which might be problematic.

The alternative seems to be mutt_extract_token(), but that raises
questions of backtick `command-embedding`; is that not a problem, on the
basis that mutt would always compose the buffer itself and there's no
chance of an attacker-controlled Attach: header making it in, or should
I add an M_TOKEN_SAFE flag to mutt_extract_token() to suppress backtick
processing?

Or is it okay as things are?  The $var embedding of mutt_extract_token()
should be useful, but I'm no longer awake enough to think through how
this would interact with the processing done by the call to
mutt_expand_path().

Thanks,

PS: does this list's accepted etiquette prefer that I start a new thread
    any time there's a patch for new functionality, even though it's a
    direct response to another mail?
-- 
I am keeping international relations on a peaceable footing.
You are biding your time before acting.
He is coddling tyrants.
 -- Roger BW on topic of verb conjugation
--- mutt/headers.c      2005-09-17 22:46:10.000000000 +0200
+++ mutt-attachfix/headers.c    2006-01-16 01:29:16.000000000 +0100
@@ -152,29 +152,54 @@ void mutt_edit_headers (const char *edit
       BODY *body;
       BODY *parts;
       char *q;
+      int proceed = 1;
 
       p = cur->data + 7;
       SKIPWS (p);
       if (*p)
       {
-       if ((q = strpbrk (p, " \t")))
+       if ((*p == '"') && *(p+1))
+       {
+         q = p + 1;
+         while (q && *q && (q = strchr (q, '"')))
+         {
+           if (*(q-1) != '\\')
+             break;
+           ++q;
+         }
+         if ((!q) || (q < (p+2))) {
+           mutt_pretty_mailbox (p);
+           mutt_error (_("%s: unable to match quotes"), p);
+           proceed = 0;
+         }
+         else
+         {
+           mutt_substrcpy (path, p+1, q, sizeof (path));
+           if (*++q)
+             SKIPWS (q);
+         }
+       }
+       else if ((q = strpbrk (p, " \t")))
        {
          mutt_substrcpy (path, p, q, sizeof (path));
          SKIPWS (q);
        }
        else
          strfcpy (path, p, sizeof (path));
-       mutt_expand_path (path, sizeof (path));
-       if ((body = mutt_make_file_attach (path)))
-       {
-         body->description = safe_strdup (q);
-         for (parts = msg->content; parts->next; parts = parts->next) ;
-         parts->next = body;
-       }
-       else
+       if (proceed)
        {
-         mutt_pretty_mailbox (path);
-         mutt_error (_("%s: unable to attach file"), path);
+         mutt_expand_path (path, sizeof (path));
+         if ((body = mutt_make_file_attach (path)))
+         {
+           body->description = safe_strdup (q);
+           for (parts = msg->content; parts->next; parts = parts->next) ;
+           parts->next = body;
+         }
+         else
+         {
+           mutt_pretty_mailbox (path);
+           mutt_error (_("%s: unable to attach file"), path);
+         }
        }
       }
       keep = 0;