diff --git a/MailMergeLib/MessageConfig.cs b/MailMergeLib/MessageConfig.cs index 4b2f0b6..6177c4b 100644 --- a/MailMergeLib/MessageConfig.cs +++ b/MailMergeLib/MessageConfig.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using System.IO; using System.Text; using MimeKit; @@ -12,11 +13,13 @@ namespace MailMergeLib [YAXSerializableType(FieldsToSerialize = YAXSerializationFields.AttributedFieldsOnly, Options = YAXSerializationOptions.DontSerializeNullObjects)] public class MessageConfig { + private string _fileBaseDirectory = Path.GetTempPath(); + /// /// CTOR for MailMergeMessage configuration. /// public MessageConfig() - {} + { } /// /// Content transfer encoding for text like HTML. @@ -69,7 +72,25 @@ private string CultureInfoName /// It is useful for retrieval of inline attachments (linked resources of the HTML body). /// [YAXSerializableField] - public string FileBaseDirectory { get; set; } = Path.GetTempPath(); + public string FileBaseDirectory + { + get => _fileBaseDirectory; + set + { + if (string.IsNullOrWhiteSpace(value)) + { + _fileBaseDirectory = Path.GetTempPath(); + return; + } + + if (!Tools.IsFullPath(value)) + { + throw new ArgumentException($"{value} is not a full path for property {nameof(FileBaseDirectory)}."); + } + + _fileBaseDirectory = value; + } + } /// /// If true, empty or illegal recipient addresses will be discarded. @@ -136,18 +157,18 @@ private string StandardFromAddressText #region *** Equality *** protected bool Equals(MessageConfig other) { - return TextTransferEncoding == other.TextTransferEncoding && - BinaryTransferEncoding == other.BinaryTransferEncoding && - Equals(CharacterEncoding, other.CharacterEncoding) && - Equals(CultureInfo, other.CultureInfo) && - string.Equals(FileBaseDirectory, other.FileBaseDirectory) && - IgnoreIllegalRecipientAddresses == other.IgnoreIllegalRecipientAddresses && + return TextTransferEncoding == other.TextTransferEncoding && + BinaryTransferEncoding == other.BinaryTransferEncoding && + Equals(CharacterEncoding, other.CharacterEncoding) && + Equals(CultureInfo, other.CultureInfo) && + string.Equals(FileBaseDirectory, other.FileBaseDirectory) && + IgnoreIllegalRecipientAddresses == other.IgnoreIllegalRecipientAddresses && IgnoreMissingInlineAttachments == other.IgnoreMissingInlineAttachments && IgnoreMissingFileAttachments == other.IgnoreMissingFileAttachments && Priority == other.Priority && - Equals(StandardFromAddress, other.StandardFromAddress) && - string.Equals(Organization, other.Organization) && - string.Equals(Xmailer, other.Xmailer) && + Equals(StandardFromAddress, other.StandardFromAddress) && + string.Equals(Organization, other.Organization) && + string.Equals(Xmailer, other.Xmailer) && SmartFormatterConfig.Equals(other.SmartFormatterConfig); } @@ -164,22 +185,22 @@ public override bool Equals(object obj) if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; - return Equals((MessageConfig) obj); + return Equals((MessageConfig)obj); } public override int GetHashCode() { unchecked { - var hashCode = (int) TextTransferEncoding; - hashCode = (hashCode * 397) ^ (int) BinaryTransferEncoding; + var hashCode = (int)TextTransferEncoding; + hashCode = (hashCode * 397) ^ (int)BinaryTransferEncoding; hashCode = (hashCode * 397) ^ (CharacterEncoding != null ? CharacterEncoding.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (CultureInfo != null ? CultureInfo.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (FileBaseDirectory != null ? FileBaseDirectory.GetHashCode() : 0); hashCode = (hashCode * 397) ^ IgnoreIllegalRecipientAddresses.GetHashCode(); hashCode = (hashCode * 397) ^ IgnoreMissingInlineAttachments.GetHashCode(); hashCode = (hashCode * 397) ^ IgnoreMissingFileAttachments.GetHashCode(); - hashCode = (hashCode * 397) ^ (int) Priority; + hashCode = (hashCode * 397) ^ (int)Priority; hashCode = (hashCode * 397) ^ (StandardFromAddress != null ? StandardFromAddress.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (Organization != null ? Organization.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (Xmailer != null ? Xmailer.GetHashCode() : 0); diff --git a/MailMergeLib/Tools.cs b/MailMergeLib/Tools.cs index ada04c7..6979f78 100644 --- a/MailMergeLib/Tools.cs +++ b/MailMergeLib/Tools.cs @@ -12,6 +12,26 @@ namespace MailMergeLib /// public static class Tools { + /// + /// Checks whether the given path is a full path + /// + /// + /// Accepts X:\ and \\UNC\PATH, rejects empty string, \ and X: + /// + /// + /// Returns true if the path is absolute, else false. + public static bool IsFullPath(string path) + { + if (string.IsNullOrWhiteSpace(path) || path.IndexOfAny(Path.GetInvalidPathChars()) != -1 || !Path.IsPathRooted(path)) + return false; + + var pathRoot = Path.GetPathRoot(path); + if (pathRoot.Length <= 2) // Accepts X:\ and \\UNC\PATH, rejects empty string, \ and X: + return false; + + return !(pathRoot == path && pathRoot.StartsWith("\\\\") && pathRoot.IndexOf('\\', 2) == -1); // A UNC server name without a share name (e.g "\\NAME") is invalid + } + /// /// Combines the specified filename with the basename of /// to form a full path to file or directory. diff --git a/UnitTests/MessageFactory.cs b/UnitTests/MessageFactory.cs index 529db05..96cfdd3 100644 --- a/UnitTests/MessageFactory.cs +++ b/UnitTests/MessageFactory.cs @@ -89,7 +89,7 @@ public static MailMergeMessage GetMessageWithAllPropertiesSet() mmm.FileAttachments.Add(new FileAttachment(Path.GetFullPath(Path.Combine(TestFileFolders.FilesAbsPath, PdfFile)), "information.pdf")); mmm.StringAttachments.Add(new StringAttachment("some content", "content.txt")); mmm.Headers.Add(HeaderId.Comments, "some comments for header"); - mmm.Config = new MessageConfig() + mmm.Config = new MailMergeLib.MessageConfig() { FileBaseDirectory = TestFileFolders.FilesAbsPath, CharacterEncoding = Encoding.UTF32, diff --git a/UnitTests/Message_Config.cs b/UnitTests/Message_Config.cs new file mode 100644 index 0000000..23d1aa3 --- /dev/null +++ b/UnitTests/Message_Config.cs @@ -0,0 +1,33 @@ +using System; +using System.IO; +using MailMergeLib; +using NUnit.Framework; + +namespace UnitTests +{ + [TestFixture] + public class Message_Config + { + private MessageConfig _msgConfig = new MessageConfig(); + private string _tempPath = Path.GetTempPath(); + + [TestCase(" \t", "?")] + [TestCase(" ", "?")] + [TestCase("", "?")] + [TestCase(null, "?")] + [TestCase("\\noFullPath", null)] + [TestCase("C:\\some\\path\\to\\folder", "C:\\some\\path\\to\\folder")] + public void SetFileBaseDirectory(string path, string expected) + { + if (expected == "?") expected = Path.GetTempPath(); + if (expected == null) + { + Assert.Throws(() => _msgConfig.FileBaseDirectory = path); + return; + } + + _msgConfig.FileBaseDirectory = path; + Assert.AreEqual(expected, _msgConfig.FileBaseDirectory); + } + } +} diff --git a/UnitTests/Settings_Serialization.cs b/UnitTests/Settings_Serialization.cs index bc69184..dd8cb5b 100644 --- a/UnitTests/Settings_Serialization.cs +++ b/UnitTests/Settings_Serialization.cs @@ -42,7 +42,7 @@ public void Setup() ConvertCharacterStringLiterals = true }, Xmailer = "MailMergeLib 5", - FileBaseDirectory = "Path-to-Base-Dir", + FileBaseDirectory = "C:\\Path-to-Base-Dir", // must be a full path, not necessarily existing TextTransferEncoding = ContentEncoding.QuotedPrintable, BinaryTransferEncoding = ContentEncoding.UUEncode }, diff --git a/UnitTests/TestFiles/Msg01.xml b/UnitTests/TestFiles/Msg01.xml index 3f7e83b..ba1fbf3 100644 --- a/UnitTests/TestFiles/Msg01.xml +++ b/UnitTests/TestFiles/Msg01.xml @@ -54,7 +54,7 @@ Base64 utf-32 de-DE - d:\Documents\Visual Studio 2015\Projects\MailMergeLib-5\UnitTests\bin\Debug\..\..\TestFiles\ + C:\ False True True @@ -71,12 +71,12 @@ - d:\Documents\Visual Studio 2015\Projects\MailMergeLib-5\UnitTests\bin\Debug\..\..\TestFiles\LogFile.log + ..\..\TestFiles\LogFile.log Log file from {Date:yyyy-MM-dd}.log text/plain - d:\Documents\Visual Studio 2015\Projects\MailMergeLib-5\UnitTests\bin\Debug\..\..\TestFiles\Sample.pdf + ..\..\TestFiles\Sample.pdf information.pdf application/pdf @@ -90,7 +90,7 @@ - d:\Documents\Visual Studio 2015\Projects\MailMergeLib-5\UnitTests\bin\Debug\..\..\TestFiles\error.jpg + ..\..\TestFiles\error.jpg error-image.jpg image/jpeg diff --git a/UnitTests/TestFiles/Msg02.xml b/UnitTests/TestFiles/Msg02.xml index e9186cc..d843cbc 100644 --- a/UnitTests/TestFiles/Msg02.xml +++ b/UnitTests/TestFiles/Msg02.xml @@ -54,7 +54,7 @@ Base64 utf-32 de-DE - d:\Documents\Visual Studio 2015\Projects\MailMergeLib-5\UnitTests\bin\Debug\..\..\TestFiles\ + C:\ False True True diff --git a/UnitTests/Tools.cs b/UnitTests/Tools.cs index 8820a20..682fbec 100644 --- a/UnitTests/Tools.cs +++ b/UnitTests/Tools.cs @@ -1,8 +1,6 @@ using System; using System.IO; using System.Text; -using MailMergeLib; -using MimeKit; using NUnit.Framework; namespace UnitTests @@ -10,6 +8,44 @@ namespace UnitTests [TestFixture] public class Tools { + [Test] + [TestCase(@"C:\dir\file.ext", true)] + [TestCase(@"C:\dir\", true)] + [TestCase(@"C:\dir", true)] + [TestCase(@"C:\", true)] + [TestCase(@"\\unc\share\dir\file.ext", true)] + [TestCase(@"\\unc\share", true)] + [TestCase(@"file.ext", false)] + [TestCase(@"dir\file.ext", false)] + [TestCase(@"\dir\file.ext", false)] + [TestCase(@"C:", false)] + [TestCase(@"C:dir\file.ext", false)] + [TestCase(@"\dir", false)] // An "absolute", but not "full" path + [TestCase(null, false, false)] + [TestCase("", false, false)] + [TestCase(" ", false, false)] + [TestCase(@"C:\inval|d", false, false)] + [TestCase(@"\\is_this_a_dir_or_a_hostname", false, false)] + public static void IsFullPath(string path, bool expectedIsFull, bool expectedIsValid = true) + { + Assert.AreEqual(expectedIsFull, MailMergeLib.Tools.IsFullPath(path), "IsFullPath('" + path + "')"); + + if (expectedIsFull) + { + Assert.AreEqual(path, Path.GetFullPath(path)); + } + else if (expectedIsValid) + { + Assert.AreNotEqual(path, Path.GetFullPath(path)); + } + else + { + Assert.That(() => Path.GetFullPath(path), Throws.Exception); + } + } + + + [Test] [TestCase(null, null, "")] [TestCase(null, "", null)] diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index c97cb39..d6a2202 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -77,6 +77,7 @@ + @@ -94,7 +95,6 @@ - @@ -102,6 +102,9 @@ + + +