From eb3a8b0fe49507a561d3cdc1bdef65b6f99cbc65 Mon Sep 17 00:00:00 2001 From: Michael Gratton Date: Sat, 22 Aug 2020 16:23:07 +1000 Subject: [PATCH] Geary.RFC822.MessageID: Replace GMime parser with more lax parser Support parsing message IDs with the form `` (per the RFC) but also `(add-spec)` and `add-spec`. Add unit tests. --- src/engine/rfc822/rfc822-message-data.vala | 41 +++++++++++++- .../rfc822/rfc822-message-data-test.vala | 56 +++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/src/engine/rfc822/rfc822-message-data.vala b/src/engine/rfc822/rfc822-message-data.vala index 14e41f7f..d238bdec 100644 --- a/src/engine/rfc822/rfc822-message-data.vala +++ b/src/engine/rfc822/rfc822-message-data.vala @@ -46,10 +46,45 @@ public class Geary.RFC822.MessageID : } public MessageID.from_rfc822_string(string rfc822) throws Error { - if (String.is_empty_or_whitespace(rfc822)) { - throw new Error.INVALID("Empty RFC822 message id: %s", rfc822); + int len = rfc822.length; + int start = 0; + while (start < len && rfc822[start].isspace()) { + start += 1; } - base(GMime.utils_decode_message_id(rfc822)); + char end_delim = 0; + bool break_on_space = false; + if (start < len) { + switch (rfc822[start]) { + case '<': + // Standard delim + start += 1; + end_delim = '>'; + break; + + case '(': + // Non-standard delim + start += 1; + end_delim = ')'; + break; + + default: + // no other supported delimiters, so just end at white + // space or EOS + break_on_space = true; + break; + } + } + int end = start + 1; + while (end < len && + rfc822[end] != end_delim && + (!break_on_space || !rfc822[end].isspace())) { + end += 1; + } + + if (start + 1 >= end) { + throw new Error.INVALID("Empty RFC822 message id"); + } + base(rfc822.slice(start, end)); } /** diff --git a/test/engine/rfc822/rfc822-message-data-test.vala b/test/engine/rfc822/rfc822-message-data-test.vala index 9eeb27d9..d6357ff9 100644 --- a/test/engine/rfc822/rfc822-message-data-test.vala +++ b/test/engine/rfc822/rfc822-message-data-test.vala @@ -15,6 +15,7 @@ class Geary.RFC822.MessageDataTest : TestCase { add_test("header_from_rfc822", header_from_rfc822); add_test("header_names_from_rfc822", header_names_from_rfc822); add_test("PreviewText.with_header", preview_text_with_header); + add_test("MessageId.from_rfc822_string", message_id_from_rfc822_string); add_test("MessageId.to_rfc822_string", message_id_to_rfc822_string); add_test("MessageIdList.from_rfc822_string", message_id_list_from_rfc822_string); add_test("MessageIdList.merge", message_id_list_merge); @@ -111,6 +112,61 @@ class Geary.RFC822.MessageDataTest : TestCase { assert_equal(neg_half_hour_tz.to_rfc822_string(), NEG_HALF_HOUR_TZ); } + + public void message_id_from_rfc822_string() throws GLib.Error { + assert_equal( + new MessageID.from_rfc822_string("").value, + "note_895184@gitlab.gnome.org" + ); + assert_equal( + new MessageID.from_rfc822_string(" \n").value, + "note_895184@gitlab.gnome.org" + ); + assert_equal( + new MessageID.from_rfc822_string("note_895184@gitlab.gnome.org").value, + "note_895184@gitlab.gnome.org" + ); + assert_equal( + new MessageID.from_rfc822_string(" note_895184@gitlab.gnome.org\n").value, + "note_895184@gitlab.gnome.org" + ); + assert_equal( + new MessageID.from_rfc822_string("(note_895184@gitlab.gnome.org)").value, + "note_895184@gitlab.gnome.org" + ); + assert_equal( + new MessageID.from_rfc822_string("").value, + "note_895184" + ); + assert_equal( + new MessageID.from_rfc822_string("").value, + "note 895184" + ); + assert_equal( + new MessageID.from_rfc822_string(" ").value, + "id1" + ); + + try { + new MessageID.from_rfc822_string(""); + assert_not_reached(); + } catch (GLib.Error err) { + assert_error(err, new Error.INVALID("")); + } + try { + new MessageID.from_rfc822_string(" "); + assert_not_reached(); + } catch (GLib.Error err) { + assert_error(err, new Error.INVALID("")); + } + try { + new MessageID.from_rfc822_string(" \n"); + assert_not_reached(); + } catch (GLib.Error err) { + assert_error(err, new Error.INVALID("")); + } + } + public void message_id_to_rfc822_string() throws GLib.Error { assert_equal( new MessageID("note_895184@gitlab.gnome.org").to_rfc822_string(),