]> granicus.if.org Git - mutt/commitdiff
Escape option values for variable queries and completion to ensure they're parsable
authorRocco Rutte <pdmef@gmx.net>
Mon, 10 Sep 2007 06:07:31 +0000 (08:07 +0200)
committerRocco Rutte <pdmef@gmx.net>
Mon, 10 Sep 2007 06:07:31 +0000 (08:07 +0200)
ChangeLog
init.c

index 73c621806721a3b70588e0a0a6a4ebdc6f888c70..9b4b8750807d4734bd70dd25c40276a14f4277d3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-09-09 15:48 -0700  Andreas  <Andreas Jaggi>  (4e9445a06369)
+
+       * imap/imap.c: Let imap_complete_hosts work with the last mailbox
+       (closes #2949). This was an off-by-one error in the mailbox loop.
+
+2007-09-09 15:20 -0700  Julien  <Julien Cristau>  (7e60c2515318)
+
+       * ChangeLog, mutt_ssl_gnutls.c: Only check whether GNUTLS error is
+       fatal when an error occurs (closes #2954). The API for GNUTLS
+       changed to require this in 1.7.18.
+
 2007-09-08 15:30 -0700  Brendan Cully  <brendan@kublai.com>  (1e4a6efddc81)
 
        * prepare: autoreconf --include doesn't pass its argument to aclocal.
diff --git a/init.c b/init.c
index fa4f5bec0c0d5675fec1d1dd73bf33d60e5f2dd7..0a327cb02ca96289a232a88485f2353c1564c2f1 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1630,6 +1630,60 @@ static void mutt_restore_default (struct option_t *p)
     set_option (OPTREDRAWTREE);
 }
 
+static size_t escape_string (char *dst, size_t len, const char* src)
+{
+  char* p = dst;
+
+  if (!len)
+    return 0;
+  len--; /* save room for \0 */
+#define ESC_CHAR(C)    do { *p++ = '\\'; if (p - dst < len) *p++ = C; } while(0)
+  while (p - dst < len && src && *src)
+  {
+    switch (*src)
+    {
+    case '\n':
+      ESC_CHAR('n');
+      break;
+    case '\r':
+      ESC_CHAR('r');
+      break;
+    case '\t':
+      ESC_CHAR('t');
+      break;
+    default:
+      if ((*src == '\\' || *src == '"') && p - dst < len - 1)
+       *p++ = '\\';
+      *p++ = *src;
+    }
+    src++;
+  }
+#undef ESC_CHAR
+  *p = '\0';
+  return p - dst;
+}
+
+static void pretty_var (char *dst, size_t len, const char *option, const char *val)
+{
+  char *p;
+
+  if (!len)
+    return;
+
+  strfcpy (dst, option, len);
+  len--; /* save room for \0 */
+  p = dst + mutt_strlen (dst);
+
+  if (p - dst < len)
+    *p++ = '=';
+  if (p - dst < len)
+    *p++ = '"';
+  p += escape_string (p, len - (p - dst) + 1, val);    /* \0 terminate it */
+  if (p - dst < len)
+    *p++ = '"';
+  *p = 0;
+}
+
 static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
 {
   int query, unset, inv, reset, r = 0;
@@ -1783,7 +1837,7 @@ static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
         {
           if ((val = myvar_get (myvar)))
           {
-            snprintf (err->data, err->dsize, "%s=\"%s\"", myvar, val);
+           pretty_var (err->data, err->dsize, myvar, val);
             break;
           }
           else
@@ -1798,12 +1852,18 @@ static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
          rfc822_write_address (_tmp, sizeof (_tmp), *((ADDRESS **) MuttVars[idx].data), 0);
          val = _tmp;
        }
+       else if (DTYPE (MuttVars[idx].type) == DT_PATH)
+       {
+         _tmp[0] = '\0';
+         strfcpy (_tmp, *((char **) MuttVars[idx].data), sizeof (_tmp));
+         mutt_pretty_mailbox (_tmp);
+         val = _tmp;
+       }
        else
          val = *((char **) MuttVars[idx].data);
        
        /* user requested the value of this variable */
-       snprintf (err->data, err->dsize, "%s=\"%s\"", MuttVars[idx].option,
-                 NONULL (val));
+       pretty_var (err->data, err->dsize, MuttVars[idx].option, NONULL(val));
        break;
       }
       else
@@ -1858,8 +1918,7 @@ static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
       if (query || *s->dptr != '=')
       {
        /* user requested the value of this variable */
-       snprintf (err->data, err->dsize, "%s=\"%s\"", MuttVars[idx].option,
-                 NONULL (ptr->pattern));
+       pretty_var (err->data, err->dsize, MuttVars[idx].option, NONULL(ptr->pattern));
        break;
       }
 
@@ -2532,7 +2591,7 @@ int mutt_var_value_complete (char *buffer, size_t len, int pos)
     {
       if ((myvarval = myvar_get(var)) != NULL)
       {
-       snprintf (pt, len - (pt - buffer), "%s=\"%s\"", var, myvarval);
+       pretty_var (pt, len - (pt - buffer), var, myvarval);
        return 1;
       }
       return 0; /* no such variable. */
@@ -2549,7 +2608,6 @@ int mutt_var_value_complete (char *buffer, size_t len, int pos)
 static int var_to_string (int idx, char* val, size_t len)
 {
   char tmp[LONG_STRING];
-  char *s, *d;
   char *vals[] = { "no", "yes", "ask-no", "ask-yes" };
 
   tmp[0] = '\0';
@@ -2635,13 +2693,7 @@ static int var_to_string (int idx, char* val, size_t len)
   else
     return 0;
 
-  for (s = tmp, d = val; *s && len - (d - val) > 2; len--)
-  {
-    if (*s == '\\' || *s == '"')
-      *d++ = '\\';
-    *d++ = *s++;
-  }
-  *d = '\0';
+  escape_string (val, len - 1, tmp);
 
   return 1;
 }