From: Thomas Roessler Date: Tue, 16 May 2000 15:23:02 +0000 (+0000) Subject: mutt_expand_path is now able to escape special characters for use in X-Git-Tag: mutt-1-3-1-rel~27 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8f38f9eaf6f1ef5236c25fae27ff0fed5cb31755;p=mutt mutt_expand_path is now able to escape special characters for use in regular expressions. This is needed to make folder-hooks work like intended. --- diff --git a/hook.c b/hook.c index 75bdfd57..e44bd03e 100644 --- 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 7dab43db..dec3e66c 100644 --- 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 90b72290..8fb13d8e 100644 --- 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); diff --git a/muttlib.c b/muttlib.c index cbeddb05..ad02ab53 100644 --- 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); } diff --git a/protos.h b/protos.h index 84287d87..d67e43ab 100644 --- 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 *);