Resolve symbolic link target relative to the symbolic link instead of the working directory (#15235) (#20943)

This commit is contained in:
Matej Kafka
2024-12-03 15:00:00 -08:00
committed by GitHub
parent c24e8e4402
commit b18eacaa83
2 changed files with 40 additions and 9 deletions
@@ -2258,16 +2258,14 @@ namespace Microsoft.PowerShell.Commands
{
exists = true;
var normalizedTargetPath = strTargetPath;
if (strTargetPath.StartsWith(".\\", StringComparison.OrdinalIgnoreCase) ||
strTargetPath.StartsWith("./", StringComparison.OrdinalIgnoreCase))
{
normalizedTargetPath = Path.Join(SessionState.Internal.CurrentLocation.ProviderPath, strTargetPath.AsSpan(2));
}
GetFileSystemInfo(normalizedTargetPath, out isDirectory);
// unify directory separators to be consistent with the rest of PowerShell even on non-Windows platforms;
// do this before resolving the target, otherwise e.g. `.\test` would break on Linux, since the combined
// path below would be something like `/path/to/cwd/.\test`
strTargetPath = strTargetPath.Replace(StringLiterals.AlternatePathSeparator, StringLiterals.DefaultPathSeparator);
// check if the target is a file or directory
var normalizedTargetPath = Path.Combine(Path.GetDirectoryName(path), strTargetPath);
GetFileSystemInfo(normalizedTargetPath, out isDirectory);
}
else
{
@@ -1,5 +1,8 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Import-Module HelpersCommon
Describe "Basic FileSystem Provider Tests" -Tags "CI" {
BeforeAll {
$testDir = "TestDir"
@@ -621,6 +624,11 @@ Describe "Hard link and symbolic link tests" -Tags "CI", "RequireAdminOnWindows"
}
Context "New-Item and hard/symbolic links" {
AfterEach {
# clean up created links after each test
Remove-Item -Exclude (Split-Path -Leaf $realFile, $realDir, $realDir2) -Recurse $TestPath/*
}
It "New-Item can create a hard link to a file" {
New-Item -ItemType HardLink -Path $hardLinkToFile -Value $realFile > $null
Test-Path $hardLinkToFile | Should -BeTrue
@@ -664,6 +672,31 @@ Describe "Hard link and symbolic link tests" -Tags "CI", "RequireAdminOnWindows"
$link.LinkType | Should -BeExactly "SymbolicLink"
$link.Target | Should -BeExactly $real.ToString()
}
It "New-Item can create a directory symbolic link to a directory using a relative path" -Skip:(-Not $IsWindows) {
$target = Split-Path -Leaf $realDir
New-Item -ItemType SymbolicLink -Path $symLinkToDir -Value $target > $null
Test-Path $symLinkToDir | Should -BeTrue
$real = Get-Item -Path $realDir
$link = Get-Item -Path $symLinkToDir
$link | Should -BeOfType System.IO.DirectoryInfo
$link.LinkType | Should -BeExactly "SymbolicLink"
$link.ResolvedTarget | Should -BeExactly $real.ToString()
$link.Target | Should -BeExactly $target
}
It "New-Item can create a directory symbolic link to a directory using a relative path with .\" -Skip:(-Not $IsWindows) {
$target = ".\$(Split-Path -Leaf $realDir)"
New-Item -ItemType SymbolicLink -Path $symLinkToDir -Value $target > $null
Test-Path $symLinkToDir | Should -BeTrue
$real = Get-Item -Path $realDir
$link = Get-Item -Path $symLinkToDir
$link | Should -BeOfType System.IO.DirectoryInfo
$link.LinkType | Should -BeExactly "SymbolicLink"
$link.ResolvedTarget | Should -BeExactly $real.ToString()
$link.Target | Should -BeExactly $target
}
It "New-Item can create a directory junction to a directory" -Skip:(-Not $IsWindows) {
New-Item -ItemType Junction -Path $junctionToDir -Value $realDir > $null
Test-Path $junctionToDir | Should -BeTrue