Re: mhbuild and long header fields

2023-09-18 Thread David Levine
Andy wrote:

> Minor correction; replace "then" with "than".
>
> Also, RFC 5322 2.1.1 does not "require" that the lines be no more than
> 78 bytes, only that it's highly recommended that they not exceed that.
> The actual line limit is 998 bytes.

Good catches, thank you!

And thank you, Phillipp.  This bug fix/enhancement is well worth your efforts.

commit 542cb12b6d0646b711772ee97c1e2aacf2bada86
Author: Philipp 
Date:   Mon Sep 18 12:50:22 2023 +0200

mhbuild now folds header field bodies to avoid lines with more than 78 
bytes.

This is recommended by RFC 5322 2.1.1. Line Length Limits.

Signed-off-by: David Levine 

David



Re: mhbuild and long header fields

2023-09-18 Thread Andy Bradford
Thus said David Levine on Sun, 17 Sep 2023 21:51:04 -0400:

> How about this?
>
> mhbuild now  folds header  field bodies to  avoid lines  with more
> then 78 bytes.
>
> This is required by RFC 5322 2.1.1. Line Length Limits.
>

Minor correction; replace "then" with "than".

Also, RFC 5322 2.1.1 does not "require" that the lines be no more than 
78 bytes, only that it's highly recommended that they not exceed that.  
The actual line limit is 998 bytes.

Thanks,

Andy




Re: mhbuild and long header fields

2023-09-18 Thread Philipp
[2023-09-17 21:51] David Levine 
> > A format-patch is attached.
>
> Thanks.  I think that the commit message should note that only header field 
> bodies are folded.  And because folding can only occur a
> t whitespace, it is possible to end up with more than 78 bytes in a line.  
> How about this?
>
> mhbuild now folds header field bodies to avoid lines with more then 78 
> bytes.
>
> This is required by RFC 5322 2.1.1. Line Length Limits.
>
> I'll add the first line of the commit message to docs/pending-release-notes.  
> And add the year to the copyright notice in fold.[hc].

Done, updated version is attached.

Philipp
From 3157510d821db9bf62b051aeb1dcc94fac1dffcd Mon Sep 17 00:00:00 2001
From: Philipp Takacs 
Date: Fri, 25 Aug 2023 09:29:42 +0200
Subject: [PATCH] mhbuild implement header folding

mhbuild now folds header field bodies to avoid lines with more then 78 bytes.

This is required by RFC 5322 2.1.1. Line Length Limits.
---
 Makefile.am   |  2 ++
 sbr/fold.c| 63 +++
 sbr/fold.h|  7 +
 test/mhbuild/test-mhbuild | 53 
 uip/mhoutsbr.c|  7 -
 5 files changed, 131 insertions(+), 1 deletion(-)
 create mode 100644 sbr/fold.c
 create mode 100644 sbr/fold.h

diff --git a/Makefile.am b/Makefile.am
index 4fc84c1d..168d9fe6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -378,6 +378,7 @@ noinst_HEADERS = \
 sbr/fmt_new.h \
 sbr/fmt_rfc2047.h \
 sbr/fmt_scan.h \
+sbr/fold.h \
 sbr/folder_addmsg.h \
 sbr/folder_delmsgs.h \
 sbr/folder_free.h \
@@ -1106,6 +1107,7 @@ sbr_libmh_a_SOURCES = \
 sbr/fmt_new.c \
 sbr/fmt_rfc2047.c \
 sbr/fmt_scan.c \
+sbr/fold.c \
 sbr/folder_addmsg.c \
 sbr/folder_delmsgs.c \
 sbr/folder_free.c \
diff --git a/sbr/fold.c b/sbr/fold.c
new file mode 100644
index ..f6047703
--- /dev/null
+++ b/sbr/fold.c
@@ -0,0 +1,63 @@
+/* fold.c -- fold a mail header field
+ *
+ * This code is Copyright (c) 2023, by the authors of nmh.  See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information. */
+
+#include "h/mh.h"
+#include "h/mime.h"
+#include "sbr/charstring.h"
+#include "fold.h"
+
+void
+fold(charstring_t dst, size_t namelen, const char *restrict body)
+{
+	const char *restrict body_next;
+	const char *restrict wsp;
+	const char *restrict wsp_next;
+	const bool crlf = strchr(body, '\r');
+	charstring_clear(dst);
+	namelen++;
+
+	while (*body) {
+		body_next = strchr(body, '\n');
+		if ((unsigned long) (body_next - body) <= MAXTEXTPERLN - namelen) {
+			charstring_push_back_chars(dst, body, body_next - body + 1, body_next - body + 1);
+			namelen = 0;
+			body = body_next + 1;
+			continue;
+		}
+		wsp = body;
+		while (namelen == 0 && (*wsp == ' ' || *wsp == '\t')) {
+			wsp++;
+		}
+		wsp = wsp_next = strpbrk(wsp, " \t");
+
+		/* if now whitespace is in the current line just print the curret line as is */
+		if (!wsp_next || wsp_next > body_next) {
+			charstring_push_back_chars(dst, body, body_next - body + 1, body_next - body + 1);
+			namelen = 0;
+			body = body_next + 1;
+			continue;
+		}
+
+		while ((unsigned long)(wsp_next - body) <= MAXTEXTPERLN - namelen) {
+			wsp = wsp_next;
+			wsp_next = strpbrk(wsp+1, " \t");
+			if (!wsp_next) {
+break;
+			}
+			if (wsp_next > body_next) {
+break;
+			}
+		}
+
+		charstring_push_back_chars(dst, body, wsp - body, wsp - body);
+		if (crlf) {
+			charstring_push_back(dst, '\r');
+		}
+		charstring_push_back(dst, '\n');
+		namelen = 0;
+		body = wsp;
+	}
+}
diff --git a/sbr/fold.h b/sbr/fold.h
new file mode 100644
index ..40bf6a49
--- /dev/null
+++ b/sbr/fold.h
@@ -0,0 +1,7 @@
+/* fold.h -- fold a mail header field
+ *
+ * This code is Copyright (c) 2023, by the authors of nmh.  See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information. */
+
+void fold(charstring_t dst, size_t namelen, const char *restrict body);
diff --git a/test/mhbuild/test-mhbuild b/test/mhbuild/test-mhbuild
index 706a804a..f8d4992b 100755
--- a/test/mhbuild/test-mhbuild
+++ b/test/mhbuild/test-mhbuild
@@ -221,5 +221,58 @@ run_test "mhbuild $f" \
 
 check "$f" "$expected"
 
+start_test "Checking for correct header folding"
+
+cat >"`mhpath new`" <<\E
+From: Somebody 
+To: Nobody 
+Subject: Test message
+References:   
+
+This is a test
+E
+
+cat > "$expected" <<\E
+From: Somebody 
+To: Nobody 
+Subject: Test message
+References: 
+  
+MIME-Version: 1.0
+Content-Type: text/plain; charset="us-ascii"
+
+This is a test
+E
+
+run_test "mhbuild -auto `mhpath last`"
+check "`mhpath last`" "$expected"
+
+start_test "Checking header folding with a to long line"
+
+cat >"`mhpath new`" <<\E
+From: Somebody 
+To: Nobody 
+Subject: Test message
+References:   
+
+This is a test
+E
+
+cat > "$expected" <<\E
+From: Somebody 
+To: Nobody 
+Subject: Tes