Skip to content

Commit

Permalink
fixed NullRef exception if BodyHtml is null/Nothing
Browse files Browse the repository at this point in the history
  • Loading branch information
jochenwezel committed Dec 3, 2024
1 parent 40e8956 commit d12e164
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 6 deletions.
1 change: 1 addition & 0 deletions CompuMaster.Net.Smtp/AssemblyInfo.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<Assembly: Runtime.CompilerServices.InternalsVisibleTo("CompuMaster.Net.Smtp.Tests")>
2 changes: 1 addition & 1 deletion CompuMaster.Net.Smtp/CompuMaster.Net.Smtp.vbproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<RootNamespace>CompuMaster.Net.Smtp</RootNamespace>
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net6.0;net48;net45</TargetFrameworks>
<Version>2024.11.04.100</Version>
<Version>2024.12.03.100</Version>
<Authors>Jochen Wezel</Authors>
<Company>CompuMaster GmbH</Company>
<Copyright>2010-2024 CompuMaster GmbH</Copyright>
Expand Down
33 changes: 30 additions & 3 deletions CompuMaster.Net.Smtp/Messaging/EMailAttachment.vb
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,49 @@ Option Explicit On
Option Strict On

''' <summary>
''' An e-mail attachment
''' An e-mail attachment
''' </summary>
Public Class EMailAttachment
Public Sub New()
'Do nothing
End Sub

''' <summary>
''' Create an attachment from local file path
''' </summary>
''' <param name="filepath"></param>
Public Sub New(filepath As String)
Me.FilePath = filepath
End Sub

''' <summary>
''' Create an attachment from local file path for reference by placeholder ID in HtmlBody
''' - WARNING: Attachments with placeholder ID and without reference in BodyHtml will be removed from message before sending
''' </summary>
''' <param name="filepath"></param>
''' <param name="placeholderName">A placeholder ID</param>
Public Sub New(filepath As String, placeholderName As String)
Me.FilePath = filepath
Me.PlaceholderInMhtmlToBeReplacedByContentID = placeholderName
End Sub

''' <summary>
''' Create an attachment from in-memory data
''' </summary>
''' <param name="data"></param>
''' <param name="filename"></param>
Public Sub New(data As Byte(), filename As String)
Me.RawData = data
Me.RawDataFilename = filename
End Sub

''' <summary>
''' Create an attachment from in-memory data for reference by placeholder ID in HtmlBody
''' - WARNING: Attachments with placeholder ID and without reference in BodyHtml will be removed from message before sending
''' </summary>
''' <param name="data"></param>
''' <param name="filename"></param>
''' <param name="placeholderName"></param>
Public Sub New(data As Byte(), filename As String, placeholderName As String)
Me.RawData = data
Me.RawDataFilename = filename
Expand Down Expand Up @@ -92,7 +118,8 @@ Public Class EMailAttachment

Private _PlaceholderInMHTML_ToReplaceWithCID As String ' <Obsolete("Use ContentID instead", False), System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _
''' <summary>
''' A placeholder string (without prefix "cid:") in the HTML code of the message (there it must be with prefix "cid:") which shall be replaced by the CID code of the attachment
''' A placeholder string (without prefix "cid:") in the HTML code of the message (there it must be with prefix "cid:") which shall be replaced by the CID code of the attachment
''' - WARNING: Attachments with placeholder ID and without reference in BodyHtml will be removed from message before sending
''' </summary>
''' <remarks>
''' <para>Define the placeholder which shall be replaced by the Content-ID for the contents of a file to the email. Emails formatted in HTML can include images with this information and internally reference the image through a "cid" hyperlink.</para>
Expand Down Expand Up @@ -136,7 +163,7 @@ Public Class EMailAttachment
#Disable Warning CA2249 ' Erwägen Sie die Verwendung von "string.Contains" anstelle von "string.IndexOf"
'remove attachments with missing references
For MyCounter As Integer = attachments.Count - 1 To 0 Step -1
If attachments(MyCounter).PlaceholderInMhtmlToBeReplacedByContentID <> Nothing AndAlso htmlBody.IndexOf(attachments(MyCounter).PlaceholderInMhtmlToBeReplacedByContentID) = -1 Then
If attachments(MyCounter).PlaceholderInMhtmlToBeReplacedByContentID <> Nothing AndAlso If(htmlBody, "").IndexOf(attachments(MyCounter).PlaceholderInMhtmlToBeReplacedByContentID) = -1 Then
'html doesn't contain any reference to the embedded object - removing attachment
attachments.RemoveAt(MyCounter)
End If
Expand Down
4 changes: 2 additions & 2 deletions CompuMaster.Net.Smtp/Messaging/EMailMessage.vb
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,9 @@ Public Class EMailMessage
End Function

''' <summary>
''' Prepare HTML and attachments for embedded images feature, initialize all list fields if null/Nothing
''' Prepare HTML and attachments for embedded images feature, cleanup attachments with placeholder but without reference from BodyHtml, initialize all list fields if null/Nothing
''' </summary>
Friend Sub PrepareForSending()
Public Sub PrepareForSending()
'Fix HTML and attachments
EMailAttachment.FixHtmlContentIDs(Me.BodyHtml, Me.EMailAttachments)
'Init missing list instances
Expand Down
100 changes: 100 additions & 0 deletions Tests/EMailMessageTest.vb
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,104 @@ Imports CompuMaster.Net.Smtp
Assert.Pass()
End Sub

<Test> Public Sub FixHtmlContentIDs()
Dim Attachments As List(Of CompuMaster.Net.Smtp.EMailAttachment)

EMailAttachment.FixHtmlContentIDs("", Nothing)

Attachments = New List(Of CompuMaster.Net.Smtp.EMailAttachment)
EMailAttachment.FixHtmlContentIDs("", Attachments)
Assert.That(Attachments.Count, [Is].EqualTo(0))

Attachments = New List(Of CompuMaster.Net.Smtp.EMailAttachment)
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment())
EMailAttachment.FixHtmlContentIDs(Nothing, Attachments)
Assert.That(Attachments.Count, [Is].EqualTo(1))

Attachments = CreateEMailAttachmentsSample1()
EMailAttachment.FixHtmlContentIDs(Nothing, Attachments)
Assert.That(Attachments.Count, [Is].EqualTo(0))

Attachments = CreateEMailAttachmentsSample1()
EMailAttachment.FixHtmlContentIDs("<html>" &
"<img src=""cid:" & Attachments(0).PlaceholderInMhtmlToBeReplacedByContentID & """/>" &
"<img src=""cid:" & Attachments(1).PlaceholderInMhtmlToBeReplacedByContentID & """/>" &
"<img src=""cid:" & Attachments(2).PlaceholderInMhtmlToBeReplacedByContentID & """/>" &
"<img src=""cid:" & Attachments(3).PlaceholderInMhtmlToBeReplacedByContentID & """/>" &
"<img src=""cid:" & Attachments(4).PlaceholderInMhtmlToBeReplacedByContentID & """/>" &
"</html>", Attachments)
Assert.That(Attachments.Count, [Is].EqualTo(5))

Attachments = CreateEMailAttachmentsSample1()
EMailAttachment.FixHtmlContentIDs("<html>" &
"<img src=""cid:" & Attachments(0).PlaceholderInMhtmlToBeReplacedByContentID & """/>" &
"</html>", Attachments)
Assert.That(Attachments.Count, [Is].EqualTo(1))

Attachments = CreateEMailAttachmentsSample2()
EMailAttachment.FixHtmlContentIDs("<html>" &
"</html>", Attachments)
Assert.That(Attachments.Count, [Is].EqualTo(2))

Attachments = CreateEMailAttachmentsSample2()
EMailAttachment.FixHtmlContentIDs("<html>" &
"<img src=""cid:" & Attachments(0).PlaceholderInMhtmlToBeReplacedByContentID & """/>" &
"<img src=""cid:" & Attachments(3).PlaceholderInMhtmlToBeReplacedByContentID & """/>" &
"</html>", Attachments)
Assert.That(Attachments.Count, [Is].EqualTo(4))
End Sub

Private Function CreateEMailAttachmentsSample1() As List(Of CompuMaster.Net.Smtp.EMailAttachment)
Dim Attachments As New List(Of CompuMaster.Net.Smtp.EMailAttachment)
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment() With {
.FilePath = Nothing,
.RawDataFilename = "ProjectDetails_CM-4825_Fachhandwerk360 Dreier+Herber GbR (DEB300336) _ Helpdesk _ IT Management + Support.pdf.pdf",
.RawDataOriginFilename = "ProjectDetails_CM-4825_Fachhandwerk360 Dreier+Herber GbR (DEB300336) _ Helpdesk _ IT Management + Support.pdf.pdf",
.RawData = New Byte() {1, 2, 3},
.PlaceholderInMhtmlToBeReplacedByContentID = "ed642552-3e6c-41ac-8984-85b24ff2ba0c"
})
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment() With {
.FilePath = Nothing,
.RawDataFilename = "ProjectDetails_CM-4825_Overview_Fachhandwerk360 Dreier+Herber GbR (DEB300336) _ Helpdesk _ IT Management + Support.pdf.pdf",
.RawDataOriginFilename = "ProjectDetails_CM-4825_Overview_Fachhandwerk360 Dreier+Herber GbR (DEB300336) _ Helpdesk _ IT Management + Support.pdf.pdf",
.RawData = New Byte() {1, 2, 3},
.PlaceholderInMhtmlToBeReplacedByContentID = "62ac3106-82c2-44dd-bc03-cc29f674fc0b"
})
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment() With {
.FilePath = Nothing,
.RawDataFilename = "ProjectDetails_CM-4825_MainCategories_Fachhandwerk360 Dreier+Herber GbR (DEB300336) _ Helpdesk _ IT Management + Support.pdf.pdf",
.RawDataOriginFilename = "ProjectDetails_CM-4825_MainCategories_Fachhandwerk360 Dreier+Herber GbR (DEB300336) _ Helpdesk _ IT Management + Support.pdf.pdf",
.RawData = New Byte() {1, 2, 3},
.PlaceholderInMhtmlToBeReplacedByContentID = "4ff43e11-fa0a-49f7-984c-7bd2869d87f2"
})
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment() With {
.FilePath = "RE559902886.pdf",
.RawDataFilename = Nothing,
.RawDataOriginFilename = Nothing,
.RawData = Nothing,
.PlaceholderInMhtmlToBeReplacedByContentID = "4b38e763-79b0-470f-80bd-d493c6b2eb9f"
})
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment() With {
.FilePath = "RE559902886_printer.pdf",
.RawDataFilename = Nothing,
.RawDataOriginFilename = Nothing,
.RawData = Nothing,
.PlaceholderInMhtmlToBeReplacedByContentID = "676fdb55-af32-4c13-b70a-933e4d20dedf"
})
Return Attachments
End Function

''' <summary>
''' Sample attachments: 2 with placeholder + 2 without placeholder
''' </summary>
''' <returns></returns>
Private Function CreateEMailAttachmentsSample2() As List(Of CompuMaster.Net.Smtp.EMailAttachment)
Dim Attachments As New List(Of CompuMaster.Net.Smtp.EMailAttachment)
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment(New Byte() {1, 2, 3}, "ProjectDetails_CM-4825_Fachhandwerk360 Dreier+Herber GbR (DEB300336) _ Helpdesk _ IT Management + Support.pdf.pdf", "ed642552-3e6c-41ac-8984-85b24ff2ba0c"))
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment(New Byte() {1, 2, 3}, "ProjectDetails_CM-4825_Overview_Fachhandwerk360 Dreier+Herber GbR (DEB300336) _ Helpdesk _ IT Management + Support.pdf.pdf"))
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment("RE559902886.pdf"))
Attachments.Add(New CompuMaster.Net.Smtp.EMailAttachment("RE559902886_printer.pdf", "676fdb55-af32-4c13-b70a-933e4d20dedf"))
Return Attachments
End Function

End Class

0 comments on commit d12e164

Please sign in to comment.