From 6bc2b55fdf99bf70cf11bbc2a37ffa20aa9881d5 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Fri, 29 Mar 2019 13:22:52 -0700 Subject: [PATCH] return correct casing of filesystem path during normalization --- .../namespaces/FileSystemProvider.cs | 41 ++++++++++++++++++- .../Set-Location.Tests.ps1 | 6 +++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index b62454ac5..733b12eb0 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -98,7 +98,46 @@ namespace Microsoft.PowerShell.Commands /// private static string NormalizePath(string path) { - return path.Replace(StringLiterals.AlternatePathSeparator, StringLiterals.DefaultPathSeparator); + return GetCorrectCasedPath(path.Replace(StringLiterals.AlternatePathSeparator, StringLiterals.DefaultPathSeparator)); + } + + /// + /// Get the correct casing for a path. This method assumes it's being called by NormalizePath() + /// so that the path is already normalized. + /// + /// + /// The path to retrieve. + /// + /// + /// The path with accurate casing if item exists, otherwise it returns path that was passed in. + /// + private static string GetCorrectCasedPath(string path) + { + string exactPath = string.Empty; + if (File.Exists(path) || Directory.Exists(path)) + { + foreach (string item in path.Split(StringLiterals.DefaultPathSeparator)) + { + if (string.IsNullOrEmpty(exactPath)) + { + exactPath = item + StringLiterals.DefaultPathSeparator; + } + else if (string.IsNullOrEmpty(item)) + { + // This handles the trailing slash case + continue; + } + else + { + exactPath = Directory.GetFileSystemEntries(exactPath, item).First(); + } + } + return exactPath; + } + else + { + return path; + } } /// 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 5824419f3..c401003c2 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 @@ -70,6 +70,12 @@ Describe "Set-Location" -Tags "CI" { Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand" } + It "Should use actual casing of folder on case-insensitive filesystem" -Skip:($IsLinux) { + $testPath = New-Item -ItemType Directory -Path testdrive:/teST + Set-Location $testPath.FullName.ToUpper() + $(Get-Location).Path | Should -BeExactly $testPath.FullName + } + Context 'Set-Location with no arguments' { It 'Should go to $env:HOME when Set-Location run with no arguments from FileSystem provider' {