Fix Test-Path -IsValid to check for invalid path and filename characters (#21358) (#23931)

Co-authored-by: Steve Lee <slee@microsoft.com>
This commit is contained in:
Aditya Patwardhan
2024-06-11 16:05:59 -07:00
committed by GitHub
co-authored by Steve Lee
parent 0296c14637
commit dc60e20cfb
2 changed files with 57 additions and 0 deletions
@@ -1080,6 +1080,21 @@ namespace Microsoft.PowerShell.Commands
}
}
// .NET introduced a change where invalid characters are accepted https://learn.microsoft.com/en-us/dotnet/core/compatibility/2.1#path-apis-dont-throw-an-exception-for-invalid-characters
// We need to check for invalid characters ourselves. `Path.GetInvalidFileNameChars()` is a supserset of `Path.GetInvalidPathChars()`
// Remove drive root first
string pathWithoutDriveRoot = path.Substring(Path.GetPathRoot(path).Length);
char[] invalidFileChars = Path.GetInvalidFileNameChars();
foreach (string segment in pathWithoutDriveRoot.Split(Path.DirectorySeparatorChar))
{
if (segment.IndexOfAny(invalidFileChars) != -1)
{
return false;
}
}
return true;
}
@@ -110,6 +110,48 @@ Describe "Test-Path" -Tags "CI" {
Test-Path -Path $badPath -IsValid | Should -BeFalse
}
It 'Windows paths should be valid: <path>' -skip:(!$IsWindows) -TestCases @(
@{ path = "C:\Program Files" }
@{ path = "C:\Program Files (x86)\" }
@{ path = "filesystem::z:\foo" }
@{ path = "filesystem::z:\foo\" }
@{ path = "variable::psversiontable" }
@{ path = "c:\windows\cmd.exe:test" }
) {
param($path)
Test-Path -Path $path -IsValid | Should -BeTrue
}
It 'Windows paths should be inavlid: <variant>' -Skip:(!$IsWindows) -TestCases @(
@{ variant = "wildcard"; path = "C:\Program Files\foo*" }
@{ variant = "pipe symbol"; path = "C:\Program Files|p\foo" }
@{ variant = "null char"; path = "C:\Win`u{0000}dows\System32" }
) {
param($path)
Test-Path -Path $path -IsValid | Should -BeFalse
}
It 'Unix paths should be valid: <path>' -Skip:($IsWindows) -TestCases @(
@{ path = "/usr/bin" }
@{ path = "/usr/bin/" }
@{ path = "filesystem::/usr/bin" }
@{ path = "filesystem::/usr/bin/" }
@{ path = "variable::psversiontable" }
@{ path = "/usr/bi*n/test" }
@{ path = "/usr/bin/tes*t" }
) {
param($path)
Test-Path -Path $path -IsValid | Should -BeTrue
}
It 'Unix paths should be invalid: <variant>' -Skip:($IsWindows) -TestCases @(
@{ variant = "null in path"; path = "/usr/bi`u{0000}n/test" }
@{ variant = "null in filename"; path = "/usr/bin/t`u{0000}est" }
) {
param($path)
Test-Path -Path $path -IsValid | Should -BeFalse
}
It "Should return true on paths containing spaces when the path is surrounded in quotes" {
Test-Path -Path "/totally a valid/path" -IsValid | Should -BeTrue
}