[geary/mjog/934-gmail-duplicate-messages: 2/4] Geary.RFC822.MessageID: Replace GMime parser with more lax parser




commit eb3a8b0fe49507a561d3cdc1bdef65b6f99cbc65
Author: Michael Gratton <mike vee net>
Date:   Sat Aug 22 16:23:07 2020 +1000

    Geary.RFC822.MessageID: Replace GMime parser with more lax parser
    
    Support parsing message IDs with the form `<add-spec>` (per the RFC)
    but also `(add-spec)` and `add-spec`.
    
    Add unit tests.

 src/engine/rfc822/rfc822-message-data.vala       | 41 +++++++++++++++--
 test/engine/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 14e41f7fe..d238bdec1 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 9eeb27d9a..d6357ff95 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("<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(" 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("<note_895184>").value,
+           "note_895184"
+        );
+        assert_equal(
+            new MessageID.from_rfc822_string("<note 895184>").value,
+            "note 895184"
+        );
+        assert_equal(
+            new MessageID.from_rfc822_string("<id1> <id2>").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(),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]