From e31ff55e33605906ea375ed90f7ae30fadb412fc Mon Sep 17 00:00:00 2001
From: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
Date: Wed, 5 Jan 2022 18:54:23 +0200
Subject: [PATCH] Handle invalid dates more gracefully
Closes #766
---
.../MarkdownVisitors/HtmlMarkdownVisitor.cs | 10 ++++++++--
.../MarkdownVisitors/PlainTextMarkdownVisitor.cs | 4 +++-
.../Markdown/Parsing/MarkdownParser.cs | 16 +++++++++-------
.../Markdown/UnixTimestampNode.cs | 3 ++-
4 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/HtmlMarkdownVisitor.cs b/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/HtmlMarkdownVisitor.cs
index 10e393e..20db27c 100644
--- a/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/HtmlMarkdownVisitor.cs
+++ b/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/HtmlMarkdownVisitor.cs
@@ -159,12 +159,18 @@ internal partial class HtmlMarkdownVisitor : MarkdownVisitor
protected override MarkdownNode VisitUnixTimestamp(UnixTimestampNode timestamp)
{
+ var dateString = timestamp.Date is not null
+ ? _context.FormatDate(timestamp.Date.Value)
+ : "Invalid date";
+
// Timestamp tooltips always use full date regardless of the configured format
- var longDateString = timestamp.Value.ToLocalString("dddd, MMMM d, yyyy h:mm tt");
+ var longDateString = timestamp.Date is not null
+ ? timestamp.Date.Value.ToLocalString("dddd, MMMM d, yyyy h:mm tt")
+ : "Invalid date";
_buffer
.Append($"")
- .Append(HtmlEncode(_context.FormatDate(timestamp.Value)))
+ .Append(HtmlEncode(dateString))
.Append("");
return base.VisitUnixTimestamp(timestamp);
diff --git a/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/PlainTextMarkdownVisitor.cs b/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/PlainTextMarkdownVisitor.cs
index b165127..1c3f614 100644
--- a/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/PlainTextMarkdownVisitor.cs
+++ b/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/PlainTextMarkdownVisitor.cs
@@ -73,7 +73,9 @@ internal partial class PlainTextMarkdownVisitor : MarkdownVisitor
protected override MarkdownNode VisitUnixTimestamp(UnixTimestampNode timestamp)
{
_buffer.Append(
- _context.FormatDate(timestamp.Value)
+ timestamp.Date is not null
+ ? _context.FormatDate(timestamp.Date.Value)
+ : "Invalid date"
);
return base.VisitUnixTimestamp(timestamp);
diff --git a/DiscordChatExporter.Core/Markdown/Parsing/MarkdownParser.cs b/DiscordChatExporter.Core/Markdown/Parsing/MarkdownParser.cs
index d82bb74..a0e9041 100644
--- a/DiscordChatExporter.Core/Markdown/Parsing/MarkdownParser.cs
+++ b/DiscordChatExporter.Core/Markdown/Parsing/MarkdownParser.cs
@@ -235,7 +235,7 @@ internal static partial class MarkdownParser
// Capture or
private static readonly IMatcher UnixTimestampNodeMatcher = new RegexMatcher(
- new Regex("", DefaultRegexOptions),
+ new Regex("", DefaultRegexOptions),
(_, m) =>
{
// TODO: support formatting parameters
@@ -244,17 +244,19 @@ internal static partial class MarkdownParser
if (!long.TryParse(m.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture,
out var offset))
{
- return null;
+ return new UnixTimestampNode(null);
}
- // Bound check
+ try
+ {
+ return new UnixTimestampNode(DateTimeOffset.UnixEpoch + TimeSpan.FromSeconds(offset));
+ }
// https://github.com/Tyrrrz/DiscordChatExporter/issues/681
- if (offset < TimeSpan.MinValue.TotalSeconds || offset > TimeSpan.MaxValue.TotalSeconds)
+ // https://github.com/Tyrrrz/DiscordChatExporter/issues/766
+ catch (Exception ex) when (ex is ArgumentOutOfRangeException or OverflowException)
{
- return null;
+ return new UnixTimestampNode(null);
}
-
- return new UnixTimestampNode(DateTimeOffset.UnixEpoch + TimeSpan.FromSeconds(offset));
}
);
diff --git a/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs b/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs
index f053466..82a81c2 100644
--- a/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs
+++ b/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs
@@ -2,4 +2,5 @@
namespace DiscordChatExporter.Core.Markdown;
-internal record UnixTimestampNode(DateTimeOffset Value) : MarkdownNode;
\ No newline at end of file
+// Null means invalid date
+internal record UnixTimestampNode(DateTimeOffset? Date) : MarkdownNode;
\ No newline at end of file