Re: smtpfront-qmail does not strip double-quotes from FROM/TO address

Bruce Guenter <[email protected]> Fri, 8 Jul 2005 00:22:35 -0600
Newsgroups gmane.comp.sysutils.bgware
Message-ID <[email protected]>
On Fri, Jul 01, 2005 at 09:21:52PM +0900, SATOH Fumiyasu wrote:
> Is this a bug of smtpfront-qmail?

Yes, and I had to almost completely rewrite the address parser to deal
with it.  The following patch fixes the problem (according to my
testing).  It also deals with stripping source routing and handles
escaped characters, both of which were missing from the original.
-- 
Bruce Guenter <[email protected]> http://em.ca/~bruceg/ http://untroubled.org/
OpenPGP key: 699980E8 / D0B7 C8DD 365D A395 29DA  2E2A E96F B2DC 6999 80E8

--- smtp-commands.c	(revision 342)
+++ smtp-commands.c	(working copy)
@@ -42,27 +42,47 @@
 
 static int parse_addr_arg(void)
 {
-  unsigned start;
-  unsigned len;
-  unsigned end;
+  unsigned i;
+  char term;
+  int quoted;
   
   if (!str_truncate(&addr, 0)) return 0;
   if (!str_truncate(&params, 0)) return 0;
-  
-  for (start = 0; start < arg.len &&
-	 (arg.s[start] != LBRACE && arg.s[start] != COLON); ++start) ;
-  if (arg.s[start] != LBRACE)
-    for (++start; start < arg.len &&
-	   (arg.s[start] == SPACE || arg.s[start] == TAB); ++start) ;
-  if (arg.s[start] == LBRACE) ++start;
-  if (start >= arg.len) return 1;
-  if ((end = str_findnext(&arg, RBRACE, start)) == (unsigned)-1) end = arg.len;
-  len = end - start;
-  if (!str_copyb(&addr, arg.s+start, len)) return 0;
-  if (arg.s[end] == RBRACE) ++end;
-  while (arg.s[end] == SPACE) ++end;
-  if (!str_copyb(&params, arg.s+end, arg.len-end)) return 0;
+
+  addr.len = 0;
+  if ((i = str_findfirst(&arg, LBRACE) + 1) != 0)
+    term = RBRACE;
+  else {
+    term = SPACE;
+    if ((i = str_findfirst(&arg, COLON) + 1) == 0)
+      if ((i = str_findfirst(&arg, SPACE) + 1) == 0)
+	return 0;
+    while (i < arg.len && arg.s[i] == SPACE)
+      ++i;
+  }
+
+  for (quoted = 0; i < arg.len && (quoted || arg.s[i] != term); ++i) {
+    switch (arg.s[i]) {
+    case QUOTE:
+      quoted = !quoted;
+      break;
+    case ESCAPE:
+      ++i;
+      /* fall through */
+    default:
+      if (!str_catc(&addr, arg.s[i])) return 0;
+    }
+  }
+  ++i;
+  while (i < arg.len && arg.s[i] == SPACE) ++i;
+  if (!str_copyb(&params, arg.s+i, arg.len-i)) return 0;
   str_subst(&params, ' ', 0);
+
+  /* strip source routing */
+  if (addr.s[0] == AT
+      && (i = str_findfirst(&addr, COLON) + 1) != 0)
+    str_lcut(&addr, i);
+    
   return 1;
 }
 
--- constants.h	(revision 342)
+++ constants.h	(working copy)
@@ -10,5 +10,7 @@
 #define LBRACE '<'
 #define RBRACE '>'
 #define PERIOD '.'
+#define ESCAPE '\\'
+#define QUOTE '"'
 
 #endif
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFCzhur6W+y3GmZgOgRAq9RAJ9xRY3TzAE9tAFrOxLiQeWs0HfTxQCfXYUv
fgorVPXVS76nTgUEBh0k460=
=eyfO
-----END PGP SIGNATURE-----