The format strings are placed in single quotes.  mutt_system() invokes
sh, so escape the single quotes using bourne-shell syntax: '\''


# HG changeset patch
# User Kevin McCarthy <ke...@8t8.us>
# Date 1478734910 28800
#      Wed Nov 09 15:41:50 2016 -0800
# Node ID d3d59df8a6906f40693f4861ac5ce6df22cf0754
# Parent  c24e9d27e0522d95a103ba5662562f714ea1379b
Compress: escape single quotes when invoking the compress/decompress commands.

The format strings are placed in single quotes.  mutt_system() invokes
sh, so escape the single quotes using bourne-shell syntax: '\''

diff --git a/compress.c b/compress.c
--- a/compress.c
+++ b/compress.c
@@ -293,16 +293,59 @@
   FREE (&ci->append);
 
   unlock_realpath (ctx);
 
   FREE (&ctx->compress_info);
 }
 
 /**
+ * escape_path - Escapes single quotes in a path for a command string.
+ * @src - the path to escape.
+ *
+ * Returns: a pointer to the escaped string.
+ */
+static char *
+escape_path (char *src)
+{
+  static char dest[HUGE_STRING];
+  char *destp = dest;
+  int destsize = 0;
+
+  if (!src)
+    return NULL;
+
+  while (*src && (destsize < sizeof(dest) - 1))
+  {
+    if (*src != '\'')
+    {
+      *destp++ = *src++;
+      destsize++;
+    }
+    else
+    {
+      /* convert ' into '\'' */
+      if (destsize + 4 < sizeof(dest))
+      {
+        *destp++ = *src++;
+        *destp++ = '\\';
+        *destp++ = '\'';
+        *destp++ = '\'';
+        destsize += 4;
+      }
+      else
+        break;
+    }
+  }
+  *destp = '\0';
+
+  return dest;
+}
+
+/**
  * cb_format_str - Expand the filenames in the command string
  * @dest:        Buffer in which to save string
  * @destlen:     Buffer length
  * @col:         Starting column, UNUSED
  * @cols:        Number of screen columns, UNUSED
  * @op:          printf-like operator, e.g. 't'
  * @src:         printf-like format string
  * @fmt:         Field formatting string, UNUSED
@@ -325,21 +368,21 @@
     return src;
 
   CONTEXT *ctx = (CONTEXT *) data;
 
   switch (op)
   {
     case 'f':
       /* Compressed file */
-      snprintf (dest, destlen, "%s", ctx->realpath);
+      snprintf (dest, destlen, "%s", NONULL (escape_path (ctx->realpath)));
       break;
     case 't':
       /* Plaintext, temporary file */
-      snprintf (dest, destlen, "%s", ctx->path);
+      snprintf (dest, destlen, "%s", NONULL (escape_path (ctx->path)));
       break;
   }
   return src;
 }
 
 /**
  * expand_command_str - Expand placeholders in command string
  * @ctx:    Mailbox for paths
diff --git a/doc/manual.xml.head b/doc/manual.xml.head
--- a/doc/manual.xml.head
+++ b/doc/manual.xml.head
@@ -8480,18 +8480,19 @@
       <arg choice="plain">
         <replaceable class="parameter">shell-command</replaceable>
       </arg>
     </cmdsynopsis>
 
     <para>
       The shell-command must contain two placeholders for filenames:
       <literal>%f</literal> and <literal>%t</literal>.  These represent
-      <quote>from</quote> and <quote>to</quote> filenames.  It's a good idea to
-      put quotes around these placeholders.
+      <quote>from</quote> and <quote>to</quote> filenames.  These placeholders
+      should be placed inside single-quotes to prevent unintended shell
+      expansions.
     </para>
 
     <para>
       If you need the exact string <quote>%f</quote> or <quote>%t</quote> in your
       command, simply double up the <quote>%</quote> character, e.g.
       <quote>%%f</quote> or <quote>%%t</quote>.
     </para>
 
@@ -8689,24 +8690,16 @@
 
       <para>
         Encrypted files are decrypted into temporary files which are
         stored in the <link linkend="tmpdir">$tmpdir</link> directory.
         This could be a security risk.
       </para>
     </sect3>
   </sect2>
-
-  <sect2 id="compress-known-bugs">
-    <title>Known Bugs</title>
-
-    <itemizedlist>
-      <listitem><para>The Compressed Folder hooks cannot deal with filenames that contains quotes/apostrophes.</para></listitem>
-    </itemizedlist>
-  </sect2>
 </sect1>
 </chapter>
 
 <chapter id="security">
 <title>Security Considerations</title>
 
 <para>
 First of all, Mutt contains no security holes included by intention but

Reply via email to