]> granicus.if.org Git - neomutt/commitdiff
patch-1.5-tlr.alias-parse.1 - extension of patch-1.5.1-me.aliascheck.1
authorThomas Roessler <roessler@does-not-exist.org>
Mon, 11 Nov 2002 19:16:11 +0000 (19:16 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Mon, 11 Nov 2002 19:16:11 +0000 (19:16 +0000)
This patch catches the same kind of bad alias names caught by
Michael's patch.  There are some extensions:

1. Mutt makes sure that it doesn't _suggest_ bad names to the user.
2. If a name is bad, the user is informed, and may elect to fix the
   name.  In this case, mutt will automatically suggest a fixed
   version.
3. If the user insists in the bad name, it's written into the
   aliases file with proper quoting.
4. When mutt parses the aliases file, it now uses the normal
   tokenizer routines in order to properly handle quoted alias names.

alias.c
init.c
protos.h

diff --git a/alias.c b/alias.c
index cd0372170debe4895d5f7c2c6b9619ef6f4b9eaf..b31e9b5ed370745b71f087b70ddf6418f359f9b0 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -21,6 +21,7 @@
 #include "mutt_curses.h"
 
 #include <string.h>
+#include <ctype.h>
 
 ADDRESS *mutt_lookup_alias (const char *s)
 {
@@ -209,6 +210,7 @@ void mutt_create_alias (ENVELOPE *cur, ADDRESS *iadr)
 {
   ALIAS *new, *t;
   char buf[LONG_STRING], prompt[SHORT_STRING], *pc;
+  char fixed[LONG_STRING];
   FILE *rc;
   ADDRESS *adr = NULL;
 
@@ -229,7 +231,11 @@ void mutt_create_alias (ENVELOPE *cur, ADDRESS *iadr)
   }
   else
     buf[0] = '\0';
+
+  /* Don't suggest a bad alias name in the event of a strange local part. */
+  mutt_check_alias_name (buf, buf);
   
+retry_name:
   /* add a new alias */
   if (mutt_get_field (_("Alias as: "), buf, sizeof (buf), 0) != 0 || !buf[0])
     return;
@@ -240,7 +246,19 @@ void mutt_create_alias (ENVELOPE *cur, ADDRESS *iadr)
     mutt_error _("You already have an alias defined with that name!");
     return;
   }
-
+  
+  if (mutt_check_alias_name (buf, fixed))
+  {
+    switch (mutt_yesorno (_("Warning: This alias name may not work.  Fix it?"), 1))
+    {
+      case 1:  
+       strfcpy (buf, fixed, sizeof (buf));
+       goto retry_name;
+      case -1: 
+       return;
+    }
+  }
+  
   new       = safe_calloc (1, sizeof (ALIAS));
   new->self = new;
   new->name = safe_strdup (buf);
@@ -299,9 +317,13 @@ void mutt_create_alias (ENVELOPE *cur, ADDRESS *iadr)
   mutt_expand_path (buf, sizeof (buf));
   if ((rc = fopen (buf, "a")))
   {
+    if (mutt_check_alias_name (new->name, NULL))
+      mutt_quote_filename (buf, sizeof (buf), new->name);
+    else
+      strfcpy (buf, new->name, sizeof (buf));
+    fprintf (rc, "alias %s ", buf);
     buf[0] = 0;
     rfc822_write_address (buf, sizeof (buf), new->addr);
-    fprintf (rc, "alias %s ", new->name);
     write_safe_address (rc, buf);
     fputc ('\n', rc);
     fclose (rc);
@@ -311,6 +333,40 @@ void mutt_create_alias (ENVELOPE *cur, ADDRESS *iadr)
     mutt_perror (buf);
 }
 
+/* 
+ * Sanity-check an alias name:  Only characters which are non-special to both
+ * the RFC 822 and the mutt configuration parser are permitted.
+ */
+
+static int check_alias_name_char (char c)
+{
+  return (c == '-' || c == '_' || c == '+' || c == '=' || c == '.' ||
+         isalnum (c));
+}
+
+int mutt_check_alias_name (const char *s, char *d)
+{
+  int rv = 0;
+  for (; *s; s++) 
+  {
+    if (!check_alias_name_char (*s))
+    {
+      if (!d)
+       return -1;
+      else
+      {
+       *d++ = '_';
+       rv = -1;
+      }
+    }
+    else if (d)
+      *d++ = *s;
+  }
+  if (d)
+    *d++ = *s;
+  return rv;
+}
+
 /*
  * This routine looks to see if the user has an alias defined for the given
  * address.
diff --git a/init.c b/init.c
index f9b756ad17a8779ba9bfef9c8ae62aa1559eb8f1..93c30c88d391d67cf32e895ae4289d7c54460cc1 100644 (file)
--- a/init.c
+++ b/init.c
@@ -498,21 +498,19 @@ static int parse_alias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
 {
   ALIAS *tmp = Aliases;
   ALIAS *last = NULL;
-  char *p;
-  size_t len;
 
-  if ((p = strpbrk (s->dptr, " \t")) == NULL)
+  if (!MoreArgs (s))
   {
     strfcpy (err->data, _("alias: no address"), err->dsize);
     return (-1);
   }
 
-  len = p - s->dptr;
+  mutt_extract_token (buf, s, 0);
 
   /* check to see if an alias with this name already exists */
   for (; tmp; tmp = tmp->next)
   {
-    if (!mutt_strncasecmp (tmp->name, s->dptr, len) && *(tmp->name + len) == 0)
+    if (!mutt_strcasecmp (tmp->name, buf->data))
       break;
     last = tmp;
   }
@@ -522,9 +520,7 @@ static int parse_alias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
     /* create a new alias */
     tmp = (ALIAS *) safe_calloc (1, sizeof (ALIAS));
     tmp->self = tmp;
-    tmp->name = safe_malloc (len + 1);
-    memcpy (tmp->name, s->dptr, len);
-    tmp->name[len] = 0;
+    tmp->name = safe_strdup (buf->data);
     /* give the main addressbook code a chance */
     if (CurrentMenu == MENU_ALIAS)
       set_option (OPTMENUCALLER);
@@ -536,7 +532,6 @@ static int parse_alias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
     if (CurrentMenu == MENU_ALIAS)
       set_option (OPTFORCEREDRAWINDEX);
   }
-  s->dptr = p;
 
   mutt_extract_token (buf, s, M_TOKEN_QUOTE | M_TOKEN_SPACE | M_TOKEN_SEMICOLON);
   tmp->addr = mutt_parse_adrlist (tmp->addr, buf->data);
index 54e008bb8358852f9f5f88bfa533196a31f746ed..f2f73e7da8bbd9ab11eecde9e7f0f500a98c33cb 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -242,6 +242,7 @@ int mutt_buffy_notify (void);
 int mutt_builtin_editor (const char *, HEADER *, HEADER *);
 int mutt_can_decode (BODY *);
 int mutt_change_flag (HEADER *, int);
+int mutt_check_alias_name (const char *, char *);
 int mutt_check_encoding (const char *);
 int mutt_check_key (const char *);
 int mutt_check_menu (const char *);