]> granicus.if.org Git - neomutt/commitdiff
nested-if: correctly handle "<" and ">" with %?
authorAleksa Sarai <cyphar@cyphar.com>
Sun, 17 Dec 2017 13:39:08 +0000 (00:39 +1100)
committerRichard Russon <rich@flatcap.org>
Thu, 28 Dec 2017 14:18:47 +0000 (14:18 +0000)
As part of the implementation of nested-if[1], we translate old-style
conditional expandos into nested-if expandos. However, this translation
did not account for the metacharacters that need to be escaped in
nested-if expandos that are valid in old-style expandos (in particular
"<" and ">"). Correct this by escaping the relevant metacharacters.

With this patch, it is now possible to do something like

  :set status_format=" %rMail%r >%?u? +%u >?"

Without causing an ">" to be included if %u is 0 (which used to be the
case).

[1]: https://www.neomutt.org/feature/nested-if

Fixes #1001

doc/manual.xml.head
muttlib.c

index f9338956c4c38abe90d32f8c0ab7ab5cdf30091c..c597b90613b0cea7d3e87fdb1614bd7a9569f131 100644 (file)
@@ -11866,6 +11866,10 @@ set index_format='%4C %Z %{%b %d} %-25.25n %&lt;M?[%M] %s&amp;%s%* %&lt;l?%l&amp
             <para>Richard Russon
             <email>rich@flatcap.org</email></para>
           </listitem>
+          <listitem>
+            <para>Aleksa Sarai
+            <email>cyphar@cyphar.com</email></para>
+          </listitem>
         </itemizedlist>
       </sect2>
     </sect1>
index 6d42493205a8603a83983e62c06c7f877e197074..00c565ef83d174fd21b0da96334a356245fcf57f 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -1060,20 +1060,25 @@ void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const c
         /* %?x?y&z? to %<x?y&z> where y and z are nestable */
         char *p = (char *) src;
         *p = '<';
+        /* skip over "x" */
         for (; *p && *p != '?'; p++)
           ;
         /* nothing */
         if (*p == '?')
-        {
           p++;
-        }
+        /* fix up the "y&z" section */
         for (; *p && *p != '?'; p++)
-          ;
-        /* nothing */
-        if (*p == '?')
         {
-          *p = '>';
+          /* escape '<' and '>' to work inside nested-if */
+          if ((*p == '<') || (*p == '>'))
+          {
+            memmove(p + 2, p, mutt_str_strlen(p) + 1);
+            *p++ = '\\';
+            *p++ = '\\';
+          }
         }
+        if (*p == '?')
+          *p = '>';
       }
 
       if (*src == '<')