From 1c0b49a9457c2eeed9596f5724ceb1dc31c03c42 Mon Sep 17 00:00:00 2001 From: Ilya Date: Tue, 26 May 2020 21:04:39 +0500 Subject: [PATCH 1/4] Fix New-Item to create symlink to relative path target --- .../namespaces/FileSystemProvider.cs | 16 ++++++++-- .../New-Item.Tests.ps1 | 32 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 081e51228b6..747add385b9 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -2361,12 +2361,22 @@ protected override void NewItem( // non-existing targets on either Windows or Linux. try { - exists = GetFileSystemInfo(strTargetPath, out isDirectory) != null; - - // Pretend the target exists if we're making a symbolic link. if (itemType == ItemType.SymbolicLink) { exists = true; + + var normalizedTargetPath = strTargetPath; + if (strTargetPath.StartsWith(".\\", StringComparison.OrdinalIgnoreCase) || + strTargetPath.StartsWith("./", StringComparison.OrdinalIgnoreCase)) + { + normalizedTargetPath = Path.Join(SessionState.Internal.CurrentLocation.ProviderPath, strTargetPath.AsSpan().Slice(2)); + } + + GetFileSystemInfo(normalizedTargetPath, out isDirectory); + } + else + { + exists = GetFileSystemInfo(strTargetPath, out isDirectory) != null; } } catch (Exception e) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index d6c98fc0695..8ee15912bd4 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -268,6 +268,38 @@ Describe "New-Item with links" -Tags @('CI', 'RequireAdminOnWindows') { } } +Describe "New-Item: symlink with absolute/relative path test" -Tags @('CI', 'RequireAdminOnWindows') { + BeforeAll { + Push-Location TestDrive:/ + $null = New-Item -Type Directory someDir + $null = New-Item -Type File someFile + } + + AfterAll { + Pop-Location + } + + It "Symlink with absolute path to existing directory behaves like a directory" { + New-Item -Type SymbolicLink someDirLinkAbsolute -Target (Convert-Path someDir) + Get-Item someDirLinkAbsolute | Should -BeOfType System.IO.DirectoryInfo + } + + It "Symlink with relative path to existing directory behaves like a directory" { + New-Item -Type SymbolicLink someDirLinkRelative -Target .\someDir + Get-Item someDirLinkRelative | Should -BeOfType System.IO.DirectoryInfo + } + + It "Symlink with absolute path to existing file behaves like a file" { + New-Item -Type SymbolicLink someFileLinkAbsolute -Target (Convert-Path someFile) + Get-Item someFileLinkAbsolute | Should -BeOfType System.IO.FileInfo + } + + It "Symlink with relative path to existing file behaves like a file" { + New-Item -Type SymbolicLink someFileLinkRelative -Target ./someFile + Get-Item someFileLinkRelative | Should -BeOfType System.IO.FileInfo + } +} + Describe "New-Item with links fails for non elevated user if developer mode not enabled on Windows." -Tags "CI" { BeforeAll { $testfile = "testfile.txt" From 1fcb37118b9c28ae57f1312b6c4841c060525594 Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 1 Jun 2020 13:46:03 +0500 Subject: [PATCH 2/4] Fix MacOs test --- .../New-Item.Tests.ps1 | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index 8ee15912bd4..024066e7372 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -302,10 +302,23 @@ Describe "New-Item: symlink with absolute/relative path test" -Tags @('CI', 'Req Describe "New-Item with links fails for non elevated user if developer mode not enabled on Windows." -Tags "CI" { BeforeAll { + # on macOS, the /tmp directory is a symlink, so we'll resolve it here + $TestPath = $TestDrive + if ($IsMacOS) + { + $item = Get-Item $TestPath + $dirName = $item.BaseName + $item = Get-Item $item.PSParentPath -Force + if ($item.LinkType -eq "SymbolicLink") + { + $TestPath = Join-Path $item.Target $dirName + } + } + $testfile = "testfile.txt" $testlink = "testlink" - $FullyQualifiedFile = Join-Path -Path $TestDrive -ChildPath $testfile - $TestFilePath = Join-Path -Path $TestDrive -ChildPath $testlink + $FullyQualifiedFile = Join-Path -Path $TestPath -ChildPath $testfile + $TestFilePath = Join-Path -Path $TestPath -ChildPath $testlink $developerModeEnabled = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock -ErrorAction SilentlyContinue).AllowDevelopmentWithoutDevLicense -eq 1 $minBuildRequired = [System.Environment]::OSVersion.Version -ge "10.0.14972" $developerMode = $developerModeEnabled -and $minBuildRequired From 906b3184f5e6ba9f59212add91bb2f3898a388fc Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 1 Jun 2020 14:10:36 +0500 Subject: [PATCH 3/4] Fix MacOs test 2 --- .../New-Item.Tests.ps1 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index 024066e7372..5544140adf9 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -270,7 +270,20 @@ Describe "New-Item with links" -Tags @('CI', 'RequireAdminOnWindows') { Describe "New-Item: symlink with absolute/relative path test" -Tags @('CI', 'RequireAdminOnWindows') { BeforeAll { - Push-Location TestDrive:/ + # on macOS, the /tmp directory is a symlink, so we'll resolve it here + $TestPath = $TestDrive + if ($IsMacOS) + { + $item = Get-Item $TestPath + $dirName = $item.BaseName + $item = Get-Item $item.PSParentPath -Force + if ($item.LinkType -eq "SymbolicLink") + { + $TestPath = Join-Path $item.Target $dirName + } + } + + Push-Location $TestPath $null = New-Item -Type Directory someDir $null = New-Item -Type File someFile } From f2b56f7b006c62bad8dc0d1fc5c143a127b223db Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 1 Jun 2020 15:29:21 +0500 Subject: [PATCH 4/4] Normalize relative path --- .../namespaces/FileSystemProvider.cs | 2 ++ .../Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 | 1 + 2 files changed, 3 insertions(+) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 747add385b9..d502a8c24df 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -2373,6 +2373,8 @@ protected override void NewItem( } GetFileSystemInfo(normalizedTargetPath, out isDirectory); + + strTargetPath = strTargetPath.Replace(StringLiterals.AlternatePathSeparator, StringLiterals.DefaultPathSeparator); } else { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index 5544140adf9..2860271b3c8 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -298,6 +298,7 @@ Describe "New-Item: symlink with absolute/relative path test" -Tags @('CI', 'Req } It "Symlink with relative path to existing directory behaves like a directory" { + # PowerShell should normalize '.\someDir' to './someDir' as needed. New-Item -Type SymbolicLink someDirLinkRelative -Target .\someDir Get-Item someDirLinkRelative | Should -BeOfType System.IO.DirectoryInfo }