]> granicus.if.org Git - mutt/commitdiff
mutt_expand_path is now able to escape special characters for use in
authorThomas Roessler <roessler@does-not-exist.org>
Tue, 16 May 2000 15:23:02 +0000 (15:23 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Tue, 16 May 2000 15:23:02 +0000 (15:23 +0000)
regular expressions.  This is needed to make folder-hooks work like
intended.

hook.c
lib.c
lib.h
muttlib.c
protos.h

diff --git a/hook.c b/hook.c
index 75bdfd5739aa6eff233a86d69d51a664f828a0c0..e44bd03e6f4f140d2cd825222e076580a5cdec96 100644 (file)
--- a/hook.c
+++ b/hook.c
@@ -79,7 +79,7 @@ int mutt_parse_hook (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
   if (data & (M_FOLDERHOOK | M_MBOXHOOK))
   {
     strfcpy (path, pattern.data, sizeof (path));
-    mutt_expand_path (path, sizeof (path));
+    _mutt_expand_path (path, sizeof (path), 1);
     FREE (&pattern.data);
     memset (&pattern, 0, sizeof (pattern));
     pattern.data = safe_strdup (path);
diff --git a/lib.c b/lib.c
index 7dab43db64629c216135f67a2d7b7f42d2bcdd16..dec3e66c2957438b44d2bfbddb3105987f29b6b5 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -401,6 +401,30 @@ void mutt_sanitize_filename (char *f, short slash)
   }
 }
 
+/* these characters must be escaped in regular expressions */
+
+static char rx_special_chars[] = "^.[$()|*+?{\\";
+
+int mutt_rx_sanitize_string (char *dest, size_t destlen, const char *src)
+{
+  while (*src && --destlen > 2)
+  {
+    if (strchr (rx_special_chars, *src))
+    {
+      *dest++ = '\\';
+      destlen--;
+    }
+    *dest++ = *src++;
+  }
+  
+  *dest = '\0';
+  
+  if (*src)
+    return -1;
+  else
+    return 0;
+}
+
 /* Read a line from ``fp'' into the dynamically allocated ``s'',
  * increasing ``s'' if necessary. The ending "\n" or "\r\n" is removed.
  * If a line ends with "\", this char and the linefeed is removed,
diff --git a/lib.h b/lib.h
index 90b72290389711dc8aaccb90822b9206898b715b..8fb13d8ee038c5fa2ddc6f9c5761d9165dd18deb 100644 (file)
--- a/lib.h
+++ b/lib.h
@@ -103,6 +103,7 @@ const char *mutt_stristr (const char *, const char *);
 
 int mutt_copy_stream (FILE *, FILE *);
 int mutt_copy_bytes (FILE *, FILE *, size_t);
+int mutt_rx_sanitize_string (char *, size_t, const char *);
 int mutt_strcasecmp (const char *, const char *);
 int mutt_strcmp (const char *, const char *);
 int mutt_strncasecmp (const char *, const char *, size_t);
index cbeddb05a710d540849b9a58c9a0a3d2f7d6cf26..ad02ab53e00041bb7cdb3c936b097a0d7a7a4189 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -302,89 +302,153 @@ void mutt_expand_link (char *newpath, const char *path, const char *link)
 }
 
 char *mutt_expand_path (char *s, size_t slen)
+{
+  return _mutt_expand_path (s, slen, 0);
+}
+
+char *_mutt_expand_path (char *s, size_t slen, int rx)
 {
   char p[_POSIX_PATH_MAX] = "";
-  char *q = NULL;
-  char *next;
+  char q[_POSIX_PATH_MAX] = "";
+  char tmp[_POSIX_PATH_MAX];
+  char *t;
+
+  char *tail = ""; 
 
-  if (*s == '~')
+  int recurse = 0;
+  
+  do 
   {
-    if (*(s + 1) == '/' || *(s + 1) == 0)
-      snprintf (p, sizeof (p), "%s%s", NONULL(Homedir), s + 1);
-    else
-    {
-      struct passwd *pw;
+    recurse = 0;
 
-      q = strchr (s + 1, '/');
-      if (q)
-       *q = 0;
-      if ((pw = getpwnam (s + 1)))
-       snprintf (p, sizeof (p), "%s/%s", pw->pw_dir, q ? q + 1 : "");
-      else
+    switch (*s)
+    {
+      case '~':
       {
-       /* user not found! */
-       if (q)
-         *q = '/';
-       return (NULL);
+       if (*(s + 1) == '/' || *(s + 1) == 0)
+       {
+         strfcpy (p, NONULL(Homedir), sizeof (p));
+         tail = s + 1;
+       }
+       else
+       {
+         struct passwd *pw;
+         if ((t = strchr (s + 1, '/'))) 
+           *t = 0;
+         if ((pw = getpwnam (s + 1)))
+         {
+           strfcpy (p, pw->pw_dir, sizeof (p));
+           if (t)
+             tail = t + 1;
+           else
+             tail = "";
+         }
+         else
+         {
+           /* user not found! */
+           if (t)
+             *t = '/';
+           *p = '\0';
+           tail = s;
+         }
+       }
       }
-    }
-  }
-  else if (*s == '=' || *s == '+')
-  {
+      break;
+      
+      case '=':
+      case '+':    
+      {
 #ifdef USE_IMAP
-  /* special case: folder = {host}: don't append slash */
-  if (mx_is_imap (NONULL (Maildir)) && Maildir[strlen (Maildir) - 1] == '}')
-    snprintf (p, sizeof (p), "%s%s", NONULL (Maildir), s + 1);
-  else
+       /* special case: folder = {host}: don't append slash */
+       if (mx_is_imap (NONULL (Maildir)) && Maildir[strlen (Maildir) - 1] == '}')
+         strfcpy (p, NONULL (Maildir), sizeof (p));
+       else
 #endif
-    snprintf (p, sizeof (p), "%s/%s", NONULL (Maildir), s + 1);
-  }
-  else if (*s == '@')
-  {
-    /* elm compatibility, @ expands alias to user name */
-    HEADER *h;
-    ADDRESS *alias;
-
-    alias = mutt_lookup_alias (s + 1);
-    if (alias != NULL)
-    {
-      h = mutt_new_header();
-      h->env = mutt_new_envelope();
-      h->env->from = h->env->to = alias;
-      mutt_default_save (p, sizeof (p), h);
-      h->env->from = h->env->to = NULL;
-      mutt_free_header (&h);
-      /* Avoid infinite recursion if the resulting folder starts with '@' */
-      if (*p != '@')
-       mutt_expand_path (p, sizeof (p));
+         snprintf (p, sizeof (p), "%s/", NONULL (Maildir));
+       
+       tail = s + 1;
+      }
+      break;
+      
+      /* elm compatibility, @ expands alias to user name */
+    
+      case '@':
+      {
+       HEADER *h;
+       ADDRESS *alias;
+       
+       if ((alias = mutt_lookup_alias (s + 1)))
+       {
+         h = mutt_new_header();
+         h->env = mutt_new_envelope();
+         h->env->from = h->env->to = alias;
+         mutt_default_save (p, sizeof (p), h);
+         h->env->from = h->env->to = NULL;
+         mutt_free_header (&h);
+         /* Avoid infinite recursion if the resulting folder starts with '@' */
+         if (*p != '@')
+           recurse = 1;
+         
+         tail = "";
+       }
+      }
+      break;
+      
+      case '>':
+      {
+       strfcpy (p, Inbox, sizeof (p));
+       tail = s + 1;
+      }
+      break;
+      
+      case '<':
+      {
+       strfcpy (p, Outbox, sizeof (p));
+       tail = s + 1;
+      }
+      break;
+      
+      case '!':
+      {
+       if (*(s+1) == '!')
+       {
+         strfcpy (p, LastFolder, sizeof (p));
+         tail = s + 2;
+       }
+       else 
+       {
+         strfcpy (p, Spoolfile, sizeof (p));
+         tail = s + 1;
+       }
+      }
+      break;
+      
+      case '-':
+      {
+       strfcpy (p, LastFolder, sizeof (p));
+       tail = s + 1;
+      }
+      break;
+      
+      default:
+      {
+       *p = '\0';
+       tail = s;
+      }
     }
-  }
-  else
-  {
-    next = s + 1;
-    if (*s == '>')
-      q = Inbox;
-    else if (*s == '<')
-      q = Outbox;
-    else if (!mutt_strcmp (s, "!!"))   /* elm compatibility */
+
+    if (rx && *p && !recurse)
     {
-      q = LastFolder;
-      next = s + 2;
+      mutt_rx_sanitize_string (q, sizeof (q), p);
+      snprintf (tmp, sizeof (tmp), "%s%s", q, tail);
     }
-    else if (*s == '!')
-      q = Spoolfile;
-    else if (*s == '-')
-      q = LastFolder;
     else
-      return s;
-
-    if (!q)
-      return s;
-    snprintf (p, sizeof (p), "%s%s", q, next);
+      snprintf (tmp, sizeof (tmp), "%s%s", p, tail);
+    
+    strfcpy (s, tmp, slen);
   }
+  while (recurse);
 
-  if (*p)
-    strfcpy (s, p, slen); /* replace the string with the expanded version. */
   return (s);
 }
 
index 84287d872ae7bcfc4b135536798e2c32d42ec123..d67e43abb31c01ac607ac9cd4b7e9eb946927433 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -115,6 +115,7 @@ const char *mutt_attach_fmt (
 
 char *mutt_charset_hook (const char *);
 char *mutt_expand_path (char *, size_t);
+char *_mutt_expand_path (char *, size_t, int);
 char *mutt_find_hook (int, const char *);
 char *mutt_gen_msgid (void);
 char *mutt_get_name (ADDRESS *);