From f59366b554f11570f67d54ab09f488ffb5f2873e Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Sat, 13 Jan 2024 09:47:56 -0500 Subject: [PATCH] Update MimeVisitor to only use interfaces (e.g. IMimePart) This allows us to include the necessary APIs for things like IMultipartEncrypted, IMultipartSigned, IApplicationPkcs7Mime, etc. while only providing the implementation of those types in a future separate MimeKit.Cryptography extension nuget package. Classes like ApplicationPgpEEncrypted and ApplicationPgpSignature, on the other hand, could be part of the core MimeKit package because they don't actually provide any crypto routines. They are just convenience classes. Another partial fix for issue #820 --- MimeKit/MimeVisitor.cs | 63 +++++++++++++---------------- MimeKit/ParserOptions.cs | 7 +--- UnitTests/HtmlPreviewVisitor.cs | 10 ++--- UnitTests/MimeVisitorTests.cs | 44 ++++++++++---------- UnitTests/TextRfc822HeadersTests.cs | 4 +- 5 files changed, 58 insertions(+), 70 deletions(-) diff --git a/MimeKit/MimeVisitor.cs b/MimeKit/MimeVisitor.cs index 4c29c775fc..ef84a36c09 100644 --- a/MimeKit/MimeVisitor.cs +++ b/MimeKit/MimeVisitor.cs @@ -24,11 +24,8 @@ // THE SOFTWARE. // -#if ENABLE_CRYPTO -using MimeKit.Cryptography; -#endif - using MimeKit.Tnef; +using MimeKit.Cryptography; namespace MimeKit { /// @@ -50,7 +47,7 @@ public abstract class MimeVisitor /// Dispatches the entity to one of the more specialized visit methods in this class. /// /// The MIME entity. - public virtual void Visit (MimeEntity entity) + public virtual void Visit (IMimeEntity entity) { entity?.Accept (this); } @@ -62,12 +59,11 @@ public virtual void Visit (MimeEntity entity) /// Dispatches the message to one of the more specialized visit methods in this class. /// /// The MIME message. - public virtual void Visit (MimeMessage message) + public virtual void Visit (IMimeMessage message) { message?.Accept (this); } -#if ENABLE_CRYPTO /// /// Visit the application/pgp-encrypted MIME entity. /// @@ -76,7 +72,7 @@ public virtual void Visit (MimeMessage message) /// /// /// The application/pgp-encrypted MIME entity. - protected internal virtual void VisitApplicationPgpEncrypted (ApplicationPgpEncrypted entity) + protected internal virtual void VisitApplicationPgpEncrypted (IApplicationPgpEncrypted entity) { VisitMimePart (entity); } @@ -89,7 +85,7 @@ protected internal virtual void VisitApplicationPgpEncrypted (ApplicationPgpEncr /// /// /// The application/pgp-signature MIME entity. - protected internal virtual void VisitApplicationPgpSignature (ApplicationPgpSignature entity) + protected internal virtual void VisitApplicationPgpSignature (IApplicationPgpSignature entity) { VisitMimePart (entity); } @@ -101,7 +97,7 @@ protected internal virtual void VisitApplicationPgpSignature (ApplicationPgpSign /// Visits the application/pkcs7-mime MIME entity. /// /// The application/pkcs7-mime MIME entity. - protected internal virtual void VisitApplicationPkcs7Mime (ApplicationPkcs7Mime entity) + protected internal virtual void VisitApplicationPkcs7Mime (IApplicationPkcs7Mime entity) { VisitMimePart (entity); } @@ -114,11 +110,10 @@ protected internal virtual void VisitApplicationPkcs7Mime (ApplicationPkcs7Mime /// /// /// The application/pkcs7-signature MIME entity. - protected internal virtual void VisitApplicationPkcs7Signature (ApplicationPkcs7Signature entity) + protected internal virtual void VisitApplicationPkcs7Signature (IApplicationPkcs7Signature entity) { VisitMimePart (entity); } -#endif /// /// Visit the message/disposition-notification MIME entity. @@ -127,7 +122,7 @@ protected internal virtual void VisitApplicationPkcs7Signature (ApplicationPkcs7 /// Visits the message/disposition-notification MIME entity. /// /// The message/disposition-notification MIME entity. - protected internal virtual void VisitMessageDispositionNotification (MessageDispositionNotification entity) + protected internal virtual void VisitMessageDispositionNotification (IMessageDispositionNotification entity) { VisitMimePart (entity); } @@ -139,7 +134,7 @@ protected internal virtual void VisitMessageDispositionNotification (MessageDisp /// Visits the message/delivery-status MIME entity. /// /// The message/delivery-status MIME entity. - protected internal virtual void VisitMessageDeliveryStatus (MessageDeliveryStatus entity) + protected internal virtual void VisitMessageDeliveryStatus (IMessageDeliveryStatus entity) { VisitMimePart (entity); } @@ -151,7 +146,7 @@ protected internal virtual void VisitMessageDeliveryStatus (MessageDeliveryStatu /// Visits the message/feedback-report MIME entity. /// /// The message/feedback-report MIME entity. - protected internal virtual void VisitMessageFeedbackReport (MessageFeedbackReport entity) + protected internal virtual void VisitMessageFeedbackReport (IMessageFeedbackReport entity) { VisitMimePart (entity); } @@ -163,7 +158,7 @@ protected internal virtual void VisitMessageFeedbackReport (MessageFeedbackRepor /// Visits the message contained within a message/rfc822 or message/news MIME entity. /// /// The message/rfc822 or message/news MIME entity. - protected virtual void VisitMessage (MessagePart entity) + protected virtual void VisitMessage (IMessagePart entity) { entity.Message?.Accept (this); } @@ -178,7 +173,7 @@ protected virtual void VisitMessage (MessagePart entity) /// /// /// The message/rfc822 or message/news MIME entity. - protected internal virtual void VisitMessagePart (MessagePart entity) + protected internal virtual void VisitMessagePart (IMessagePart entity) { VisitMimeEntity (entity); VisitMessage (entity); @@ -191,7 +186,7 @@ protected internal virtual void VisitMessagePart (MessagePart entity) /// Visits the message/partial MIME entity. /// /// The message/partial MIME entity. - protected internal virtual void VisitMessagePartial (MessagePartial entity) + protected internal virtual void VisitMessagePartial (IMessagePartial entity) { VisitMimePart (entity); } @@ -203,7 +198,7 @@ protected internal virtual void VisitMessagePartial (MessagePartial entity) /// Visits the abstract MIME entity. /// /// The MIME entity. - protected internal virtual void VisitMimeEntity (MimeEntity entity) + protected internal virtual void VisitMimeEntity (IMimeEntity entity) { } @@ -214,7 +209,7 @@ protected internal virtual void VisitMimeEntity (MimeEntity entity) /// Visits the body of the message. /// /// The message. - protected virtual void VisitBody (MimeMessage message) + protected virtual void VisitBody (IMimeMessage message) { message.Body?.Accept (this); } @@ -226,7 +221,7 @@ protected virtual void VisitBody (MimeMessage message) /// Visits the MIME message. /// /// The MIME message. - protected internal virtual void VisitMimeMessage (MimeMessage message) + protected internal virtual void VisitMimeMessage (IMimeMessage message) { VisitBody (message); } @@ -241,7 +236,7 @@ protected internal virtual void VisitMimeMessage (MimeMessage message) /// /// /// The MIME part entity. - protected internal virtual void VisitMimePart (MimePart entity) + protected internal virtual void VisitMimePart (IMimePart entity) { VisitMimeEntity (entity); } @@ -253,7 +248,7 @@ protected internal virtual void VisitMimePart (MimePart entity) /// Visits the children of a . /// /// Multipart. - protected virtual void VisitChildren (Multipart multipart) + protected virtual void VisitChildren (IMultipart multipart) { for (int i = 0; i < multipart.Count; i++) multipart[i].Accept (this); @@ -266,7 +261,7 @@ protected virtual void VisitChildren (Multipart multipart) /// Visits the abstract multipart MIME entity. /// /// The multipart MIME entity. - protected internal virtual void VisitMultipart (Multipart multipart) + protected internal virtual void VisitMultipart (IMultipart multipart) { VisitMimeEntity (multipart); VisitChildren (multipart); @@ -282,12 +277,11 @@ protected internal virtual void VisitMultipart (Multipart multipart) /// /// /// The multipart/alternative MIME entity. - protected internal virtual void VisitMultipartAlternative (MultipartAlternative alternative) + protected internal virtual void VisitMultipartAlternative (IMultipartAlternative alternative) { VisitMultipart (alternative); } -#if ENABLE_CRYPTO /// /// Visit the multipart/encrypted MIME entity. /// @@ -295,11 +289,10 @@ protected internal virtual void VisitMultipartAlternative (MultipartAlternative /// Visits the multipart/encrypted MIME entity. /// /// The multipart/encrypted MIME entity. - protected internal virtual void VisitMultipartEncrypted (MultipartEncrypted encrypted) + protected internal virtual void VisitMultipartEncrypted (IMultipartEncrypted encrypted) { VisitMultipart (encrypted); } -#endif /// /// Visit the multipart/related MIME entity. @@ -311,7 +304,7 @@ protected internal virtual void VisitMultipartEncrypted (MultipartEncrypted encr /// /// /// The multipart/related MIME entity. - protected internal virtual void VisitMultipartRelated (MultipartRelated related) + protected internal virtual void VisitMultipartRelated (IMultipartRelated related) { VisitMultipart (related); } @@ -326,12 +319,11 @@ protected internal virtual void VisitMultipartRelated (MultipartRelated related) /// /// /// The multipart/report MIME entity. - protected internal virtual void VisitMultipartReport (MultipartReport report) + protected internal virtual void VisitMultipartReport (IMultipartReport report) { VisitMultipart (report); } -#if ENABLE_CRYPTO /// /// Visit the multipart/signed MIME entity. /// @@ -339,11 +331,10 @@ protected internal virtual void VisitMultipartReport (MultipartReport report) /// Visits the multipart/signed MIME entity. /// /// The multipart/signed MIME entity. - protected internal virtual void VisitMultipartSigned (MultipartSigned signed) + protected internal virtual void VisitMultipartSigned (IMultipartSigned signed) { VisitMultipart (signed); } -#endif /// /// Visit the text-based MIME part entity. @@ -355,7 +346,7 @@ protected internal virtual void VisitMultipartSigned (MultipartSigned signed) /// /// /// The text-based MIME part entity. - protected internal virtual void VisitTextPart (TextPart entity) + protected internal virtual void VisitTextPart (ITextPart entity) { VisitMimePart (entity); } @@ -370,7 +361,7 @@ protected internal virtual void VisitTextPart (TextPart entity) /// /// /// The text/rfc822-headers MIME entity. - protected internal virtual void VisitTextRfc822Headers (TextRfc822Headers entity) + protected internal virtual void VisitTextRfc822Headers (ITextRfc822Headers entity) { VisitMessagePart (entity); } @@ -385,7 +376,7 @@ protected internal virtual void VisitTextRfc822Headers (TextRfc822Headers entity /// /// /// The Microsoft TNEF MIME part entity. - protected internal virtual void VisitTnefPart (TnefPart entity) + protected internal virtual void VisitTnefPart (ITnefPart entity) { VisitMimePart (entity); } diff --git a/MimeKit/ParserOptions.cs b/MimeKit/ParserOptions.cs index 117083144d..212099f355 100644 --- a/MimeKit/ParserOptions.cs +++ b/MimeKit/ParserOptions.cs @@ -29,12 +29,9 @@ using System.Reflection; using System.Collections.Generic; -#if ENABLE_CRYPTO -using MimeKit.Cryptography; -#endif - using MimeKit.Tnef; using MimeKit.Utils; +using MimeKit.Cryptography; namespace MimeKit { /// @@ -399,6 +396,7 @@ internal MimeEntity CreateEntity (ContentType contentType, IList
headers if (subtype.Equals ("pkcs7-signature", StringComparison.OrdinalIgnoreCase) || subtype.Equals ("x-pkcs7-signature", StringComparison.OrdinalIgnoreCase)) return new ApplicationPkcs7Signature (args); +#endif // application/pgp-encrypted if (subtype.Equals ("pgp-encrypted", StringComparison.OrdinalIgnoreCase) || @@ -409,7 +407,6 @@ internal MimeEntity CreateEntity (ContentType contentType, IList
headers if (subtype.Equals ("pgp-signature", StringComparison.OrdinalIgnoreCase) || subtype.Equals ("x-pgp-signature", StringComparison.OrdinalIgnoreCase)) return new ApplicationPgpSignature (args); -#endif // application/ms-tnef if (subtype.Equals ("ms-tnef", StringComparison.OrdinalIgnoreCase) || diff --git a/UnitTests/HtmlPreviewVisitor.cs b/UnitTests/HtmlPreviewVisitor.cs index 5259df2cf8..0a733e1073 100644 --- a/UnitTests/HtmlPreviewVisitor.cs +++ b/UnitTests/HtmlPreviewVisitor.cs @@ -33,7 +33,7 @@ namespace UnitTests { ///
class HtmlPreviewVisitor : MimeVisitor { - readonly List stack = new List (); + readonly List stack = new List (); string body; /// @@ -59,14 +59,14 @@ public string HtmlBody { get { return body ?? string.Empty; } } - protected internal override void VisitMultipartAlternative (MultipartAlternative alternative) + protected internal override void VisitMultipartAlternative (IMultipartAlternative alternative) { // walk the multipart/alternative children backwards from greatest level of faithfulness to the least faithful for (int i = alternative.Count - 1; i >= 0 && body == null; i--) alternative[i].Accept (this); } - protected internal override void VisitMultipartRelated (MultipartRelated related) + protected internal override void VisitMultipartRelated (IMultipartRelated related) { var root = related.Root; @@ -170,7 +170,7 @@ void HtmlTagCallback (HtmlTagContext ctx, HtmlWriter htmlWriter) } } - protected internal override void VisitTextPart (TextPart entity) + protected internal override void VisitTextPart (ITextPart entity) { TextConverter converter; @@ -200,7 +200,7 @@ protected internal override void VisitTextPart (TextPart entity) base.VisitTextPart (entity); } - protected internal override void VisitMessagePart (MessagePart entity) + protected internal override void VisitMessagePart (IMessagePart entity) { // don't descend into message/rfc822 parts } diff --git a/UnitTests/MimeVisitorTests.cs b/UnitTests/MimeVisitorTests.cs index 7f2a5063b7..7cd3627322 100644 --- a/UnitTests/MimeVisitorTests.cs +++ b/UnitTests/MimeVisitorTests.cs @@ -102,133 +102,133 @@ class MimeVisitorTester : MimeVisitor public int TextRfc822Headers; public int TnefPart; - protected internal override void VisitApplicationPgpEncrypted (ApplicationPgpEncrypted entity) + protected internal override void VisitApplicationPgpEncrypted (IApplicationPgpEncrypted entity) { ApplicationPgpEncrypted++; base.VisitApplicationPgpEncrypted (entity); } - protected internal override void VisitApplicationPgpSignature (ApplicationPgpSignature entity) + protected internal override void VisitApplicationPgpSignature (IApplicationPgpSignature entity) { ApplicationPgpSignature++; base.VisitApplicationPgpSignature (entity); } - protected internal override void VisitApplicationPkcs7Mime (ApplicationPkcs7Mime entity) + protected internal override void VisitApplicationPkcs7Mime (IApplicationPkcs7Mime entity) { ApplicationPkcs7Mime++; base.VisitApplicationPkcs7Mime (entity); } - protected internal override void VisitApplicationPkcs7Signature (ApplicationPkcs7Signature entity) + protected internal override void VisitApplicationPkcs7Signature (IApplicationPkcs7Signature entity) { ApplicationPkcs7Signature++; base.VisitApplicationPkcs7Signature (entity); } - protected override void VisitMessage (MessagePart entity) + protected override void VisitMessage (IMessagePart entity) { Message++; base.VisitMessage (entity); } - protected internal override void VisitMessageDeliveryStatus (MessageDeliveryStatus entity) + protected internal override void VisitMessageDeliveryStatus (IMessageDeliveryStatus entity) { MessageDeliveryStatus++; base.VisitMessageDeliveryStatus (entity); } - protected internal override void VisitMessageDispositionNotification (MessageDispositionNotification entity) + protected internal override void VisitMessageDispositionNotification (IMessageDispositionNotification entity) { MessageDispositionNotification++; base.VisitMessageDispositionNotification (entity); } - protected internal override void VisitMessageFeedbackReport (MessageFeedbackReport entity) + protected internal override void VisitMessageFeedbackReport (IMessageFeedbackReport entity) { MessageFeedbackReport++; base.VisitMessageFeedbackReport (entity); } - protected internal override void VisitMessagePart (MessagePart entity) + protected internal override void VisitMessagePart (IMessagePart entity) { MessagePart++; base.VisitMessagePart (entity); } - protected internal override void VisitMessagePartial (MessagePartial entity) + protected internal override void VisitMessagePartial (IMessagePartial entity) { MessagePartial++; base.VisitMessagePartial (entity); } - protected internal override void VisitMimeEntity (MimeEntity entity) + protected internal override void VisitMimeEntity (IMimeEntity entity) { MimeEntity++; base.VisitMimeEntity (entity); } - protected internal override void VisitMimeMessage (MimeMessage message) + protected internal override void VisitMimeMessage (IMimeMessage message) { MimeMessage++; base.VisitMimeMessage (message); } - protected internal override void VisitMimePart (MimePart entity) + protected internal override void VisitMimePart (IMimePart entity) { MimePart++; base.VisitMimePart (entity); } - protected internal override void VisitMultipart (Multipart multipart) + protected internal override void VisitMultipart (IMultipart multipart) { Multipart++; base.VisitMultipart (multipart); } - protected internal override void VisitMultipartAlternative (MultipartAlternative alternative) + protected internal override void VisitMultipartAlternative (IMultipartAlternative alternative) { MultipartAlternative++; base.VisitMultipartAlternative (alternative); } - protected internal override void VisitMultipartEncrypted (MultipartEncrypted encrypted) + protected internal override void VisitMultipartEncrypted (IMultipartEncrypted encrypted) { MultipartEncrypted++; base.VisitMultipartEncrypted (encrypted); } - protected internal override void VisitMultipartRelated (MultipartRelated related) + protected internal override void VisitMultipartRelated (IMultipartRelated related) { MultipartRelated++; base.VisitMultipartRelated (related); } - protected internal override void VisitMultipartReport (MultipartReport report) + protected internal override void VisitMultipartReport (IMultipartReport report) { MultipartReport++; base.VisitMultipartReport (report); } - protected internal override void VisitMultipartSigned (MultipartSigned signed) + protected internal override void VisitMultipartSigned (IMultipartSigned signed) { MultipartSigned++; base.VisitMultipartSigned (signed); } - protected internal override void VisitTextPart (TextPart entity) + protected internal override void VisitTextPart (ITextPart entity) { TextPart++; base.VisitTextPart (entity); } - protected internal override void VisitTextRfc822Headers (TextRfc822Headers entity) + protected internal override void VisitTextRfc822Headers (ITextRfc822Headers entity) { TextRfc822Headers++; base.VisitTextRfc822Headers (entity); } - protected internal override void VisitTnefPart (TnefPart entity) + protected internal override void VisitTnefPart (ITnefPart entity) { TnefPart++; base.VisitTnefPart (entity); diff --git a/UnitTests/TextRfc822HeadersTests.cs b/UnitTests/TextRfc822HeadersTests.cs index 18f1349ab9..5d3c48bacc 100644 --- a/UnitTests/TextRfc822HeadersTests.cs +++ b/UnitTests/TextRfc822HeadersTests.cs @@ -43,9 +43,9 @@ public void TestArgumentExceptions () class TextRfc822HeadersVisitor : MimeVisitor { - public TextRfc822Headers Rfc822Headers; + public ITextRfc822Headers Rfc822Headers; - protected internal override void VisitTextRfc822Headers (TextRfc822Headers entity) + protected internal override void VisitTextRfc822Headers (ITextRfc822Headers entity) { Rfc822Headers = entity; }