~sircmpwn/hare-users

hare-message: hare-message: Skip invalid header fields instead of aborting v1 PROPOSED

Max Schillinger: 2
 message: Replace `void` type with `done` type
 message::read_header: Skip header fields with invalid values

 3 files changed, 13 insertions(+), 6 deletions(-)
Actually, I have written a cover letter with some explanations. I don't 
know why it's not showing up neither in the mailing list nor on 
https://lists.sr.ht/~sircmpwn/hare-users/. I have used:

git send-email --compose HEAD~2

Does anybody know if `git send-email` saves sent emails anywhere?
Next try to add a cover letter:

I'm trying to use hare-message in [emailbook-hare][1] but it aborts when 
any header field contains invalid UTF-8. This happens very seldom (in 
about 0.5% of my emails), mostly in the subject field. Actually, 
emailbook-hare doesn't even look at the subject, only at From/To/Cc.

With this patch (2/2), invalid header fields are skipped and an error 
message is printed to stderr.

When somebody tries to add an invalid header field via `header_add_raw`, 
hare-message aborts nevertheless. Maybe, in this case returning an error 
would be better, too?

[1]: https://sr.ht/~maxgyver83/emailbook-hare/
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/hare-users/patches/51405/mbox | git am -3
Learn more about email & git

[PATCH hare-message 1/2] message: Replace `void` type with `done` type Export this patch

Signed-off-by: Max Schillinger <max@mxsr.de>
---
 message/canonical.ha | 2 +-
 message/header.ha    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/message/canonical.ha b/message/canonical.ha
index 0e231bc..5497f12 100644
--- a/message/canonical.ha
+++ b/message/canonical.ha
@@ -46,7 +46,7 @@ export fn canonical_mime_header_key(key: str) str = {
		const rn = match (strings::next(&iter)) {
		case let rn: rune =>
			yield rn;
		case void =>
		case done =>
			break;
		};
		if (!ascii::valid(rn) || !valid_header_field(rn: u32: u8)) {
diff --git a/message/header.ha b/message/header.ha
index cd35132..08a637d 100644
--- a/message/header.ha
+++ b/message/header.ha
@@ -481,7 +481,7 @@ fn header_field_raw(hf: *header_field) ([]u8 | errors::invalid) = {
		const rn = match (strings::next(&iter)) {
		case let rn: rune =>
			yield rn;
		case void =>
		case done =>
			break;
		};

-- 
2.44.0

[PATCH hare-message 2/2] message::read_header: Skip header fields with invalid values Export this patch

Signed-off-by: Max Schillinger <max@mxsr.de>
---
 message/header.ha | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/message/header.ha b/message/header.ha
index 08a637d..a7a4fd7 100644
--- a/message/header.ha
+++ b/message/header.ha
@@ -1,6 +1,7 @@
use ascii;
use bufio;
use bytes;
use encoding::utf8;
use errors;
use fmt;
use hash::fnv;
@@ -134,7 +135,7 @@ export fn header_add_raw(head: *header, kv: []u8) void = {
	const key = bytes::trim(kv[..colon], ' ', '\t');
	const key = canonical_mime_header_key(strings::fromutf8(key)!);
	let map = header_get_mapkey(head, key);
	const val = decode_header_value(kv[colon..]);
	const val = decode_header_value(kv[colon..])!;

	const field = alloc(new_header_field(key, val, alloc(kv...)));
	append(head.fields, field);
@@ -355,7 +356,13 @@ export fn read_header(
			continue;
		};

		const val = decode_header_value(kv[i+1..]);
		const val = match (decode_header_value(kv[i+1..])) {
		case encoding::utf8::invalid =>
			fmt::errorfln("Error: Invalid UTF8 in value for header key '{}'", key)!;
			continue;
		case let val: str =>
			yield val;
		};
		const field = alloc(header_field {
			raw = kv,
			key = key,
@@ -599,7 +606,7 @@ fn fold_line(v: []u8, max: size) ([]u8, []u8, bool) = {

// Decodes a header value, collapsing continuation lines as necessary. The
// caller must free the return value.
fn decode_header_value(v: []u8) str = {
fn decode_header_value(v: []u8) (str | encoding::utf8::invalid) = {
	const sink = memio::dynamic();
	for (true) {
		const i = match (bytes::index(v, '\n')) {
@@ -612,7 +619,7 @@ fn decode_header_value(v: []u8) str = {
		write_continued(&sink, v[..i]);
		v = v[i+1..];
	};
	return memio::string(&sink)!;
	return memio::string(&sink)?;
};

fn write_continued(sink: *memio::stream, v: []u8) void = {
-- 
2.44.0
Actually, I have written a cover letter with some explanations. I don't 
know why it's not showing up neither in the mailing list nor on 
https://lists.sr.ht/~sircmpwn/hare-users/. I have used:

git send-email --compose HEAD~2

Does anybody know if `git send-email` saves sent emails anywhere?