sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 7085ec55ef5bd7d770fead5c6e16000ebc1a2629
parent 7a035e6a53449b77cceae1d8045c51c4063b0ab6
Author: Dan Callaghan <djc@djc.id.au>
Date:   Sun, 12 May 2024 16:21:47 +1000

use a fallback date if Date header is not valid RFC2822

Use Time.rfc2822 to parse the Date header in RFC2822 format, rather than
letting Time.parse try heuristics to guess the format.

If parsing fails, use the fallback date (mtime or From line timestamp)
instead of letting Time.parse fill in the missing pieces from the
current time.

Fixes #252.

Diffstat:
M Manifest.txt | 1 +
M lib/sup/message.rb | 2 +-
M test/dummy_source.rb | 4 +++-
A test/fixtures/invalid-date.eml | 8 ++++++++
M test/test_message.rb | 13 +++++++++++++
5 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/Manifest.txt b/Manifest.txt
@@ -128,6 +128,7 @@ test/fixtures/binary-content-transfer-encoding-2.eml
 test/fixtures/blank-header-fields.eml
 test/fixtures/contacts.txt
 test/fixtures/embedded-message.eml
+test/fixtures/invalid-date.eml
 test/fixtures/mailing-list-header.eml
 test/fixtures/malicious-attachment-names.eml
 test/fixtures/missing-from-to.eml
diff --git a/lib/sup/message.rb b/lib/sup/message.rb
@@ -103,7 +103,7 @@ class Message
     when Time
       date
     when String
-      Time.parse date rescue nil
+      Time.rfc2822 date rescue nil
     end
     @date = location.fallback_date if @date.nil?
     @date = Time.utc 1970, 1, 1 if @date.nil?
diff --git a/test/dummy_source.rb b/test/dummy_source.rb
@@ -10,10 +10,12 @@ module Redwood
 class DummySource < Source
 
   attr_accessor :messages
+  attr_writer :fallback_date
 
   def initialize uri, last_date=nil, usual=true, archived=false, id=nil, labels=[]
     super uri, usual, archived, id
     @messages = nil
+    @fallback_date = Time.utc 2001, 2, 3, 4, 56, 57
   end
 
   def start_offset
@@ -61,7 +63,7 @@ class DummySource < Source
   end
 
   def fallback_date_for_message id
-    Time.utc 2001, 2, 3, 4, 56, 57
+    @fallback_date
   end
 end
 
diff --git a/test/fixtures/invalid-date.eml b/test/fixtures/invalid-date.eml
@@ -0,0 +1,8 @@
+To: person@example.invalid
+Subject: pre-RFC2822 Date header
+Content-type: text/plain
+From: anotherperson@example.invalid
+Message-Id: <6965470922807932796@example.invalid>
+Date: ons, 26 maj 1999 11:00:34 +0200 (CEST)
+
+A message body.
diff --git a/test/test_message.rb b/test/test_message.rb
@@ -359,6 +359,19 @@ class TestMessage < Minitest::Test
     fn = chunks[3].safe_filename
     assert_equal(fn, File.basename(fn))
   end
+
+  def test_invalid_date_header
+    fallback_date = Time.utc 2024, 5, 12, 15, 5, 56
+    source = DummySource.new("sup-test://test_invalid_date_header")
+    source.messages = [ fixture_path("invalid-date.eml") ]
+    source.fallback_date = fallback_date
+
+    sup_message = Message.build_from_source(source, 0)
+    sup_message.load_from_source!
+
+    assert_equal(fallback_date, sup_message.date)
+  end
+
   # TODO: test different error cases, malformed messages etc.
 
   # TODO: test different quoting styles, see that they are all divided