diff --git a/src/DemaConsulting.BuildMark/PathHelpers.cs b/src/DemaConsulting.BuildMark/PathHelpers.cs index 11252e7..45c1462 100644 --- a/src/DemaConsulting.BuildMark/PathHelpers.cs +++ b/src/DemaConsulting.BuildMark/PathHelpers.cs @@ -34,6 +34,10 @@ internal static class PathHelpers /// Thrown when relativePath contains invalid characters or path traversal sequences. internal static string SafePathCombine(string basePath, string relativePath) { + // Validate inputs + ArgumentNullException.ThrowIfNull(basePath); + ArgumentNullException.ThrowIfNull(relativePath); + // Ensure the relative path doesn't contain path traversal sequences if (relativePath.Contains("..") || Path.IsPathRooted(relativePath)) { diff --git a/test/DemaConsulting.BuildMark.Tests/PathHelpersTests.cs b/test/DemaConsulting.BuildMark.Tests/PathHelpersTests.cs index 8983134..992236e 100644 --- a/test/DemaConsulting.BuildMark.Tests/PathHelpersTests.cs +++ b/test/DemaConsulting.BuildMark.Tests/PathHelpersTests.cs @@ -43,6 +43,30 @@ public void PathHelpers_SafePathCombine_ValidPaths_CombinesCorrectly() Assert.AreEqual(Path.Combine(basePath, relativePath), result); } + /// + /// Test that SafePathCombine throws ArgumentNullException for null basePath. + /// + [TestMethod] + public void PathHelpers_SafePathCombine_NullBasePath_ThrowsArgumentNullException() + { + // Act & Assert + var exception = Assert.Throws(() => + PathHelpers.SafePathCombine(null!, "subfolder/file.txt")); + Assert.AreEqual("basePath", exception.ParamName); + } + + /// + /// Test that SafePathCombine throws ArgumentNullException for null relativePath. + /// + [TestMethod] + public void PathHelpers_SafePathCombine_NullRelativePath_ThrowsArgumentNullException() + { + // Act & Assert + var exception = Assert.Throws(() => + PathHelpers.SafePathCombine("/home/user/project", null!)); + Assert.AreEqual("relativePath", exception.ParamName); + } + /// /// Test that SafePathCombine throws ArgumentException for path traversal with double dots. ///