Subject: bug#7760: closed (Re: bug#7760: mail-mbox-from produces invalid mbox From lines when From lines are multiline)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 02 Jan 2011 02:30:04 +0000

Your bug report

#7760: mail-mbox-from produces invalid mbox From lines when From lines are multiline

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
7760: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7760
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#7760: mail-mbox-from produces invalid mbox From lines when From lines are multiline
From: Glenn Morris <[email-masked]>
To: [email-masked]
Date: Sat, 01 Jan 2011 21:36:03 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

Version: 23.3

Thanks; I applied something similar.

Subject: mail-mbox-from produces invalid mbox From lines when From lines are multiline
From: Mark Lillibridge <[email-masked]>
To: [email-masked]
Date: Wed, 29 Dec 2010 19:06:56 -0800
List-Id: <debbugs-submit.debbugs.gnu.org>

[at least version 23.1 onwards]

    Mbox from lines are required to be a single line starting with
"From "; see mail/rmail.el:720 for evidence of this:

(defvar rmail-unix-mail-delimiter
  (let ((time-zone-regexp
	 (concat "\\([A-Z]?[A-Z]?[A-Z][A-Z]\\( DST\\)?"
		 "\\|[-+]?[0-9][0-9][0-9][0-9]"
		 "\\|"
		 "\\) *")))
    (concat
     "From "

     ;; Many things can happen to an RFC 822 mailbox before it is put into
     ;; a `From' line.  The leading phrase can be stripped, e.g.
     ;; `Joe <@w.x:[email-masked]>' -> `<@w.x:[email-masked]>'.  The <> can be stripped, e.g.
     ;; `<@x.y:[email-masked]>' -> [email-masked]:[email-masked]'.  Everything starting with a CRLF
     ;; can be removed, e.g.
     ;;		From: [email-masked] (Joe	K
     ;;			User)
     ;; can yield `From [email-masked] (Joe 	K Fri Mar 22 08:11:15 1996', and
     ;;		From: Joe User
     ;;			<[email-masked]>
     ;; can yield `From Joe User Fri Mar 22 08:11:15 1996'.
     ;; The mailbox can be removed or be replaced by white space, e.g.
     ;;		From: "Joe User"{space}{tab}
     ;;			<[email-masked]>
     ;; can yield `From {space}{tab} Fri Mar 22 08:11:15 1996',
     ;; where {space} and {tab} represent the Ascii space and tab characters.
     ;; We want to match the results of any of these manglings.
     ;; The following regexp rejects names whose first characters are
     ;; obviously bogus, but after that anything goes.
     "\\([^\0-\b\n-\r\^?].*\\)? "

     ;; The time the message was sent.
     "\\([^\0-\r \^?]+\\) +"				; day of the week
     "\\([^\0-\r \^?]+\\) +"				; month
     "\\([0-3]?[0-9]\\) +"				; day of month
     "\\([0-2][0-9]:[0-5][0-9]\\(:[0-6][0-9]\\)?\\) *"	; time of day

     ;; Perhaps a time zone, specified by an abbreviation, or by a
     ;; numeric offset.
     time-zone-regexp

     ;; The year.
     " \\([0-9][0-9]+\\) *"

     ;; On some systems the time zone can appear after the year, too.
     time-zone-regexp

     ;; Old uucp cruft.
     "\\(remote from .*\\)?"

     "\n"))
  "Regexp matching the delimiter of messages in UNIX mail format
\(UNIX From lines), minus the initial ^.  Note that if you change
this expression, you must change the code in `rmail-nuke-pinhead-header'
that knows the exact ordering of the \\( \\) subexpressions.")

However, mail-mbox-from in mail/mail-utils.el:387:
(defun mail-mbox-from ()
  "Return an mbox \"From \" line for the current message.
The buffer should be narrowed to just the header."
  (let ((from (or (mail-fetch-field "from")
		  (mail-fetch-field "really-from")
		  (mail-fetch-field "sender")
		  "unknown"))
	(date (mail-fetch-field "date")))
    (format "From %s %s\n" (mail-strip-quoted-names from)
	    (or (and date
		     (ignore-errors
		      (current-time-string (date-to-time date))))
		(current-time-string)))))

produces multiple line results for messages containing multiple line
>From lines; for example, consider the following message headers from
a real message:

Return-Path: <[email-masked]>
Resent-Date: Fri, 25 Oct 1996 18:01:41 -0500 (EST)
Resent-To: [email-masked]
Date: Fri, 25 Oct 1996 18:36:19 -0400
From: Andrew Myers <[email-masked]>,
        Joseph Bank <[email-masked]>,
        Barbara Liskov <[email-masked]>
To: [email-masked]
Subject: Parameterized Types for Java

(This message may or may not meet various e-mail standards; that is
irrelevant -- mail-mbox-from must give valid results for all real
messages.)

On this message, mail-mbox-from produces the following invalid result:

"From [email-masked],
        [email-masked],
        [email-masked] Fri Oct 25 15:36:19 1996
"

I attach a fairly simple fix which ignores everything starting with a
comma or newline in the from/etc. lines.  It instead produces:

"From [email-masked] Thu Dec  1 23:37:29 1994
"

Truncating starting with a newline is justified by the comments above:

     ;; `<@x.y:[email-masked]>' -> [email-masked]:[email-masked]'.  Everything starting with a CRLF
     ;; can be removed, e.g.
     ;;		From: [email-masked] (Joe	K
     ;;			User)
     ;; can yield `From [email-masked] (Joe 	K Fri Mar 22 08:11:15 1996', and
     ;;		From: Joe User
     ;;			<[email-masked]>
     ;; can yield `From Joe User Fri Mar 22 08:11:15 1996'.

Truncating starting with a comma is to attempt to preserve the spirit of
the from line (give a single sending mailbox), but is not strictly
necessary.

- Mark

New version is:
(defun mail-mbox-from ()
  "Return an mbox \"From \" line for the current message.
The buffer should be narrowed to just the header."
  (let* ((from (or (mail-fetch-field "from")
		   (mail-fetch-field "really-from")
		   (mail-fetch-field "sender")
		   "unknown"))
	 (stripped-from (mail-strip-quoted-names from))
	 (final-from (substring stripped-from 0 
				(string-match "[,\n]" stripped-from)))
	 (date (mail-fetch-field "date")))
    (format "From %s %s\n" final-from
	    (or (and date
		     (ignore-errors
		      (current-time-string (date-to-time date))))
		(current-time-string)))))

ts-rhel5 [158]% diff new-mail-utils.el new-mail-utils2.el
390,395c390,398
<   (let ((from (or (mail-fetch-field "from")
<                 (mail-fetch-field "really-from")
<                 (mail-fetch-field "sender")
<                 "unknown"))
<       (date (mail-fetch-field "date")))
<     (format "From %s %s\n" (mail-strip-quoted-names from)
---
>   (let* ((from (or (mail-fetch-field "from")
>                  (mail-fetch-field "really-from")
>                  (mail-fetch-field "sender")
>                  "unknown"))
>        (stripped-from (mail-strip-quoted-names from))
>        (final-from (substring stripped-from 0 
>                               (string-match "[,\n]" stripped-from)))
>        (date (mail-fetch-field "date")))
>     (format "From %s %s\n" final-from