Subject: bug#53991: Fix header mangling by message-hide-headers

From: Philip Kaludercic <[email-masked]>
Date: Mon, 14 Feb 2022 09:05:06 +0000

Tags: patch

I have been having issues with mangled headers for a while not,
especially when resuming a message using C-u C-x m.  This could result
in headers being inserted right in the middle of other headers resulting
in stuff like this:

   To: bug-gnuReferences: <...>
   [email-masked]

that in the best case raises an issue when being sent, in the worse case
silently breaks without you knowing that it was broken.

It appears this was caused by setting mail-user-agent to
'gnus-user-agent.  In gnus-msg-mail, gnus-setup-message calls
message-hide-headers that would try to reorder the headers so that the
headers indicated by message-hidden-headers are placed at the beginning
of the buffer, then narrowed away.  The simplest fix for this issue in
case anyone were to stumble upon it in the future is to set the
message-hidden-headers to nil.

The more complex solution is attached below, and involves replacing the
manual end-of-headers tracking with a marker, that resolves the issue
that the previous implementation had, where end-of-headers could point
right into the middle of a header as described above.

In GNU Emacs 29.0.50 (build 6, x86_64-pc-linux-gnu, X toolkit, cairo version 1.16.0, Xaw scroll bars)
 of 2022-02-06 built on icterid
Repository revision: b0fd3ec2c0131e79b1c62e1f1beb6f29cf076120
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: Debian GNU/Linux 11 (bullseye)

Configured using:
 'configure --with-x-toolkit=athena --with-native-compilation
 'CFLAGS=-Os -march=native -mtune=native -pipe' LDFLAGS=-flto'

>From c64dae033a5ef48beb1895790d678b016f03e017 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <[email-masked]>
Date: Mon, 14 Feb 2022 09:29:04 +0100
Subject: [PATCH] Improve stability of message-hide-headers

* message.el (message-hide-headers): Use a pointer instead of tracking
  the "end-of-headers" point manually.
---
 lisp/gnus/message.el | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index a6c6a16653..9327259c60 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -8621,26 +8621,23 @@ message-hide-headers
 		   message-hidden-headers))
 	(inhibit-point-motion-hooks t)
 	(inhibit-modification-hooks t)
-	(end-of-headers (point-min)))
+	end-of-headers)
     (when regexps
       (save-excursion
 	(save-restriction
 	  (message-narrow-to-headers)
+          (setq end-of-headers (point-min-marker))
 	  (goto-char (point-min))
 	  (while (not (eobp))
 	    (if (not (message-hide-header-p regexps))
 		(message-next-header)
-	      (let ((begin (point))
-		    header header-len)
+	      (let ((begin (point)))
 		(message-next-header)
-		(setq header (buffer-substring begin (point))
-		      header-len (- (point) begin))
-		(delete-region begin (point))
-		(goto-char end-of-headers)
-		(insert header)
-		(setq end-of-headers
-		      (+ end-of-headers header-len))))))))
-    (narrow-to-region end-of-headers (point-max))))
+                (let ((header (delete-and-extract-region begin (point))))
+                  (save-excursion
+                    (goto-char end-of-headers)
+                    (insert-before-markers header))))))))
+      (narrow-to-region end-of-headers (point-max)))))
 
 (defun message-hide-header-p (regexps)
   (let ((result nil)
-- 
2.30.2

-- 
	Philip Kaludercic