Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/System.Management.Automation/namespaces/FileSystemProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2361,12 +2361,24 @@ 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);

strTargetPath = strTargetPath.Replace(StringLiterals.AlternatePathSeparator, StringLiterals.DefaultPathSeparator);
}
else
{
exists = GetFileSystemInfo(strTargetPath, out isDirectory) != null;
}
}
catch (Exception e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,71 @@ Describe "New-Item with links" -Tags @('CI', 'RequireAdminOnWindows') {
}
}

Describe "New-Item: symlink with absolute/relative path test" -Tags @('CI', 'RequireAdminOnWindows') {
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
}
}

Push-Location $TestPath
$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" {
# PowerShell should normalize '.\someDir' to './someDir' as needed.
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 {
# 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
Expand Down