<<< Date Index >>>     <<< Thread Index >>>

[PATCH] Unbreak exact address feature



Hi,

I've been using bisect to find the commit breaking the exact address feature. It turns out this is changeset cd3774ecfa9f adding IDNA support.

The problem with exact address is that for all address related headers, it adds an additional line break in the pager. This one is caused by a strncat() call in address_header_decode() since it assumes rfc822_write_adrlist() doesn't \n-terminate its output.

However, mutt_copy_hdr() doesn't strip line endings from fgets() calls so that the mutt_substrdup() assignment in rfc822_parse_adrlist() later on (in the default case) copies everything up to the end, including the \n. As a result, the pager prints the line plus \n resulting in actually two line breaks.

I know that exact address is rarely used, but shipping it broken isn't good either. So, if there're no objections against the attached patch after some time I'm going to commit and mark the feature as unbroken.

(If anybody wants to try it: it changes the header cache version resulting in cache files being rebuild)

Rocco
diff --git a/rfc822.c b/rfc822.c
index 7b05e30..4500e67 100644
--- a/rfc822.c
+++ b/rfc822.c
@@ -337,7 +337,7 @@ add_addrspec (ADDRESS **top, ADDRESS **last, const char 
*phrase,
 
 ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s)
 {
-  int ws_pending;
+  int ws_pending, nl;
   const char *begin, *ps;
   char comment[STRING], phrase[STRING];
   size_t phraselen = 0, commentlen = 0;
@@ -350,6 +350,8 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s)
     last = last->next;
 
   ws_pending = isspace ((unsigned char) *s);
+  if ((nl = mutt_strlen (s)))
+    nl = s[nl - 1] == '\n';
   
   SKIPWS (s);
   begin = s;
@@ -500,7 +502,7 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s)
   }
 #ifdef EXACT_ADDRESS
   if (last)
-    last->val = mutt_substrdup (begin, s);
+    last->val = mutt_substrdup (begin, s - nl < begin ? begin : s - nl);
 #endif
 
   return top;