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