[geary] Fix scan error when loading a message with an invalid Date header.



commit f79927430ec04b4e8d05adbef851b4746b652af1
Author: Michael James Gratton <mike vee net>
Date:   Sat Aug 4 14:43:11 2018 +1000

    Fix scan error when loading a message with an invalid Date header.
    
    Don't silently fail to parse Date headers that are actually longs, since
    that will throw an error when the message is being loaded by the
    conversation monitor. Handle cases where that error might be thrown
    gracefully so we can attempt to save/load/display the message anyway.

 .../formatted-conversation-data.vala               |  3 +--
 src/engine/imap-db/imap-db-message-row.vala        | 13 ++++++++++---
 src/engine/imap/api/imap-folder-session.vala       | 20 ++++++++++++++------
 .../imap/response/imap-fetch-data-decoder.vala     | 17 +++++++++++++++--
 src/engine/rfc822/rfc822-message-data.vala         | 22 +++++++++++++++-------
 5 files changed, 55 insertions(+), 20 deletions(-)
---
diff --git a/src/client/conversation-list/formatted-conversation-data.vala 
b/src/client/conversation-list/formatted-conversation-data.vala
index 2b428e90..f05b4845 100644
--- a/src/client/conversation-list/formatted-conversation-data.vala
+++ b/src/client/conversation-list/formatted-conversation-data.vala
@@ -104,8 +104,7 @@ public class FormattedConversationData : Geary.BaseObject {
     // Creates a formatted message data from an e-mail.
     public FormattedConversationData(Geary.App.Conversation conversation, Geary.Email preview,
         Geary.Folder folder, Gee.List<Geary.RFC822.MailboxAddress> account_owner_emails) {
-        assert(preview.fields.fulfills(ConversationListStore.REQUIRED_FIELDS));
-        
+
         this.conversation = conversation;
         this.account_owner_emails = account_owner_emails;
         use_to = (folder != null) && folder.special_folder_type.is_outgoing();
diff --git a/src/engine/imap-db/imap-db-message-row.vala b/src/engine/imap-db/imap-db-message-row.vala
index 9dcfcae4..5e52b2a6 100644
--- a/src/engine/imap-db/imap-db-message-row.vala
+++ b/src/engine/imap-db/imap-db-message-row.vala
@@ -102,9 +102,16 @@ private class Geary.ImapDB.MessageRow {
         // if the caller expects to see a DATE field, that field is set in the Email's bitmask,
         // even if the Date object is null
         Geary.Email email = new Geary.Email(id);
-        
-        if (fields.is_all_set(Geary.Email.Field.DATE))
-            email.set_send_date(!String.is_empty(date) ? new RFC822.Date(date) : null);
+
+        if (fields.is_all_set(Geary.Email.Field.DATE)) {
+            try {
+                email.set_send_date(
+                    !String.is_empty(date) ? new RFC822.Date(date) : null
+                );
+            } catch (GLib.Error err) {
+                debug("Error loading message date from db: %s", err.message);
+            }
+        }
 
         if (fields.is_all_set(Geary.Email.Field.ORIGINATORS)) {
             email.set_originators(unflatten_addresses(from),
diff --git a/src/engine/imap/api/imap-folder-session.vala b/src/engine/imap/api/imap-folder-session.vala
index aee63178..1b9e11a8 100644
--- a/src/engine/imap/api/imap-folder-session.vala
+++ b/src/engine/imap/api/imap-folder-session.vala
@@ -900,16 +900,24 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject {
         } else if (header_specifier != null && has_header_specifier) {
             RFC822.Header headers = new RFC822.Header(
                 fetched_data.body_data_map.get(header_specifier));
-            
+
             // DATE
             if (required_but_not_set(Geary.Email.Field.DATE, required_fields, email)) {
                 string? value = headers.get_header("Date");
-                if (!String.is_empty(value))
-                    email.set_send_date(new RFC822.Date(value));
-                else
-                    email.set_send_date(null);
+                RFC822.Date? date = null;
+                if (!String.is_empty(value)) {
+                    try {
+                        date = new RFC822.Date(value);
+                    } catch (GLib.Error err) {
+                        debug(
+                            "Error parsing date from FETCH response: %s",
+                            err.message
+                        );
+                    }
+                }
+                email.set_send_date(date);
             }
-            
+
             // ORIGINATORS
             if (required_but_not_set(Geary.Email.Field.ORIGINATORS, required_fields, email)) {
                 RFC822.MailboxAddresses? from = null;
diff --git a/src/engine/imap/response/imap-fetch-data-decoder.vala 
b/src/engine/imap/response/imap-fetch-data-decoder.vala
index 5464111b..5bd7c95d 100644
--- a/src/engine/imap/response/imap-fetch-data-decoder.vala
+++ b/src/engine/imap/response/imap-fetch-data-decoder.vala
@@ -144,8 +144,21 @@ public class Geary.Imap.EnvelopeDecoder : Geary.Imap.FetchDataDecoder {
         // does not supply it (optional according to RFC822); deal with this cognitive dissonance
         if (message_id != null && message_id.is_empty())
             message_id = null;
-        
-        return new Envelope((sent != null) ? new Geary.RFC822.Date(sent.ascii) : null,
+
+        Geary.RFC822.Date? sent_date = null;
+        if (sent != null) {
+            try {
+                sent_date = new RFC822.Date(sent.ascii);
+            } catch (GLib.Error err) {
+                debug(
+                    "Error parsing sent date from FETCH envelope: %s",
+                    err.message
+                );
+            }
+        }
+
+        return new Envelope(
+            sent_date,
             new Geary.RFC822.Subject.decode(subject.ascii),
             parse_addresses(from), parse_addresses(sender), parse_addresses(reply_to),
             (to != null) ? parse_addresses(to) : null, 
diff --git a/src/engine/rfc822/rfc822-message-data.vala b/src/engine/rfc822/rfc822-message-data.vala
index a643e0fa..f70f0ba4 100644
--- a/src/engine/rfc822/rfc822-message-data.vala
+++ b/src/engine/rfc822/rfc822-message-data.vala
@@ -173,22 +173,30 @@ public class Geary.RFC822.Date : Geary.RFC822.MessageData, Geary.MessageData.Abs
 
     public string? original { get; private set; }
     public DateTime value { get; private set; }
-    
+
     public Date(string iso8601) throws ImapError {
         this.as_time_t = GMime.utils_header_decode_date(iso8601, null);
         if (as_time_t == 0)
-            throw new ImapError.PARSE_ERROR("Unable to parse \"%s\": not ISO-8601 date", iso8601);
-        
-        value = new DateTime.from_unix_local(this.as_time_t);
-        original = iso8601;
+            throw new ImapError.PARSE_ERROR(
+                "Unable to parse \"%s\": Not ISO-8601 date", iso8601
+            );
+
+        DateTime? value = new DateTime.from_unix_local(this.as_time_t);
+        if (value == null) {
+            throw new ImapError.PARSE_ERROR(
+                "Unable to parse \"%s\": Outside supported range", iso8601,
+            );
+        }
+        this.value = value;
+        this.original = iso8601;
     }
-    
+
     public Date.from_date_time(DateTime datetime) {
         original = null;
         value = datetime;
         this.as_time_t = Time.datetime_to_time_t(datetime);
     }
-    
+
     /**
      * Returns the {@link Date} in ISO-8601 format.
      */


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