From 02d5492bd92da2b1af21e58c5e3fe0fa70010819 Mon Sep 17 00:00:00 2001 From: Bryan Berns Date: Sat, 11 Apr 2020 07:08:12 -0400 Subject: [PATCH 1/4] Address Set-Location & Get-Item Issue With ?/* Characters - Adjusted behavior of GetCorrectCasedPath() which attempts to search for the file on the file system in order to normalize its case. Since some file systems support wildcard characters in path names; processing needs to be skipped for these. - Added tests to detect this behavior. --- .../namespaces/FileSystemProvider.cs | 5 ++ .../Set-Location.Tests.ps1 | 55 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 23706ab1e05..996d8e062b4 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -158,6 +158,11 @@ private static string GetCorrectCasedPath(string path) // This handles short path names exactPath += StringLiterals.DefaultPathSeparator + item; } + else if (item.IndexOfAny(new char[] { '*', '?' }) >= 0) + { + // This handles literal wildcard characters that could resolve erroneously + exactPath += StringLiterals.DefaultPathSeparator + item; + } else { // Use GetFileSystemEntries to get the correct casing of this element diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 index 2fb8177ec1a..a17f53242e1 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 @@ -231,3 +231,58 @@ Describe "Set-Location" -Tags "CI" { } } } + +Describe "Set-Location: Name with special/wildcards characters" -Tags "CI" { + + BeforeAll { + + $startLocation = (Get-Location).Path + + # printable ascii characters excluding alphanumerics + $specialChars = ' !"#$%&''()*+,-./:;<=>?@[\]^_`{|}~ '.ToCharArray() + $testCases = @() + ForEach ($specialChar in $specialChars) { + If ($specialChar -ne '.') { $testCases += @{Name=([string] $specialChar)} } + $testCases += @{Name=('foo' + $specialChar)} + $testCases += @{Name=($specialChar + 'foo')} + } + } + + It "Should be able to create and set location to " -TestCases $testCases { + param ( $Name ) + + # skip unsupported characters for the current platform + if ($Name.IndexOfAny([System.IO.Path]::GetInvalidFileNameChars()) -ge 0 -or ` + ($IsWindows -and ($Name.EndsWith('.') -or $Name.EndsWith(' ')))) { + Set-ItResult -Skipped -Because "'${Name}' is not supported as directory name on this operating system." + return + } + + # note processing of '\' should be allowed on posix systems but + # is quite broken in many powershell cmdlets + if ($Name.Contains('\')) + { + Set-ItResult -Skipped -Because "path elements with backslashes are not fully supported in PowerShell on this operating system." + return + } + + $dirFullName = (Join-Path $TestDrive $Name) + + $newDir = [System.IO.Directory]::CreateDirectory($dirFullName) + $newDir.Name | Should -BeExactly $Name + + $newDirGetCheck = Get-Item -LiteralPath $dirFullName -Force + $newDirGetCheck.Name | Should -BeExactly $Name + + try { + Set-Location -LiteralPath $dirFullName + [System.IO.Path]::GetFileName((Get-Location).Path) | Should -BeExactly $Name + } + catch { + throw "Set-Location $Name Failed" + } + finally { + Set-Location -LiteralPath $startLocation + } + } +} From 7230f08bab87d90629a7da5643445dc39300ce78 Mon Sep 17 00:00:00 2001 From: Bryan Berns Date: Fri, 24 Apr 2020 07:19:50 -0400 Subject: [PATCH 2/4] Address Set-Location & Get-Item Issue With ?/* Characters - Revisions - Mark backslash test on MacOS / Linux as 'Pending' vice 'Skipped'. - Use Utils.Separators.StarOrQuestion instead of hard-coded constants. --- .../namespaces/FileSystemProvider.cs | 2 +- .../Microsoft.PowerShell.Management/Set-Location.Tests.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 996d8e062b4..8134a42528f 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -158,7 +158,7 @@ private static string GetCorrectCasedPath(string path) // This handles short path names exactPath += StringLiterals.DefaultPathSeparator + item; } - else if (item.IndexOfAny(new char[] { '*', '?' }) >= 0) + else if (item.IndexOfAny(Utils.Separators.StarOrQuestion) >= 0) { // This handles literal wildcard characters that could resolve erroneously exactPath += StringLiterals.DefaultPathSeparator + item; diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 index a17f53242e1..ea542ff84b7 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 @@ -262,7 +262,7 @@ Describe "Set-Location: Name with special/wildcards characters" -Tags "CI" { # is quite broken in many powershell cmdlets if ($Name.Contains('\')) { - Set-ItResult -Skipped -Because "path elements with backslashes are not fully supported in PowerShell on this operating system." + Set-ItResult -Pending -Because "path elements with backslashes are not fully supported in PowerShell on MacOs/Linux." return } From fed014a481df859583ec432698ad9236478fc21f Mon Sep 17 00:00:00 2001 From: Bryan Berns Date: Mon, 8 Jun 2020 23:18:04 -0400 Subject: [PATCH 3/4] Address Set-Location & Get-Item Issue With ?/* Characters - Revisions - Added failure test for a directory that contains wildcard characters. --- .../Set-Location.Tests.ps1 | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 index ea542ff84b7..3632f5925d1 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 @@ -230,6 +230,26 @@ Describe "Set-Location" -Tags "CI" { $PWD.Path | Should -Be $location.Path } } + + It 'Should should not match directory containing wildcard character *' -Skip:([System.IO.Path]::GetInvalidFileNameChars() -contains '*') { + Set-Location $TestDrive + $currentPath = (Get-Location).Path + $literalPathActual = Join-Path $TestDrive '*****' + $literalPathAttempt = Join-Path $TestDrive 'aaaaa' + New-Item -ItemType Directory -Path $literalPathActual + { Set-Location -LiteralPath $literalPathAttempt -ErrorAction Stop } | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand" + (Get-Location).Path | Should -BeExactly $currentPath + } + + It 'Should should not match directory containing wildcard character ?' -Skip:([System.IO.Path]::GetInvalidFileNameChars() -contains '?') { + Set-Location $TestDrive + $currentPath = (Get-Location).Path + $literalPathActual = Join-Path $TestDrive '?????' + $literalPathAttempt = Join-Path $TestDrive 'aaaaa' + New-Item -ItemType Directory -Path $literalPathActual + { Set-Location -LiteralPath $literalPathAttempt -ErrorAction Stop } | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand" + (Get-Location).Path | Should -BeExactly $currentPath + } } Describe "Set-Location: Name with special/wildcards characters" -Tags "CI" { From 737df8fb2cd66f761fdaa32bf7ad3922d8555451 Mon Sep 17 00:00:00 2001 From: Bryan Berns Date: Tue, 9 Jun 2020 05:15:35 -0400 Subject: [PATCH 4/4] Address Set-Location & Get-Item Issue With ?/* Characters - Revisions --- .../namespaces/FileSystemProvider.cs | 9 ++------- .../Set-Location.Tests.ps1 | 6 +++--- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 8134a42528f..d858f8ab5c4 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -153,14 +153,9 @@ private static string GetCorrectCasedPath(string path) break; } - else if (item.Contains('~')) + else if (item.Contains('~') || item.IndexOfAny(Utils.Separators.StarOrQuestion) >= 0) { - // This handles short path names - exactPath += StringLiterals.DefaultPathSeparator + item; - } - else if (item.IndexOfAny(Utils.Separators.StarOrQuestion) >= 0) - { - // This handles literal wildcard characters that could resolve erroneously + // This handles short path names and wildcard characters that could resolve erroneously exactPath += StringLiterals.DefaultPathSeparator + item; } else diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 index 3632f5925d1..6148244f044 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 @@ -231,7 +231,7 @@ Describe "Set-Location" -Tags "CI" { } } - It 'Should should not match directory containing wildcard character *' -Skip:([System.IO.Path]::GetInvalidFileNameChars() -contains '*') { + It 'Should not match directory containing wildcard character *' -Skip:([System.IO.Path]::GetInvalidFileNameChars() -contains '*') { Set-Location $TestDrive $currentPath = (Get-Location).Path $literalPathActual = Join-Path $TestDrive '*****' @@ -241,7 +241,7 @@ Describe "Set-Location" -Tags "CI" { (Get-Location).Path | Should -BeExactly $currentPath } - It 'Should should not match directory containing wildcard character ?' -Skip:([System.IO.Path]::GetInvalidFileNameChars() -contains '?') { + It 'Should not match directory containing wildcard character ?' -Skip:([System.IO.Path]::GetInvalidFileNameChars() -contains '?') { Set-Location $TestDrive $currentPath = (Get-Location).Path $literalPathActual = Join-Path $TestDrive '?????' @@ -299,7 +299,7 @@ Describe "Set-Location: Name with special/wildcards characters" -Tags "CI" { [System.IO.Path]::GetFileName((Get-Location).Path) | Should -BeExactly $Name } catch { - throw "Set-Location $Name Failed" + throw ("Set-Location $Name Failed; Exception: " + $_.Exception.Message) } finally { Set-Location -LiteralPath $startLocation