diff --git a/src/System.Management.Automation/engine/SessionStateContainer.cs b/src/System.Management.Automation/engine/SessionStateContainer.cs index 546965c83cf..1a9f7988678 100644 --- a/src/System.Management.Automation/engine/SessionStateContainer.cs +++ b/src/System.Management.Automation/engine/SessionStateContainer.cs @@ -3443,7 +3443,7 @@ internal void NewItem( if (string.IsNullOrEmpty(name)) { string providerPath = - Globber.GetProviderPath(resolvePath, context, out provider, out driveInfo); + Globber.GetProviderPath(WildcardPattern.Unescape(resolvePath), context, out provider, out driveInfo); providerInstance = GetProviderInstance(provider); providerPaths.Add(providerPath); @@ -3535,9 +3535,14 @@ internal void NewItem( throw PSTraceSource.NewInvalidOperationException(SessionStateStrings.PathNotFound, targetPath); } - // If the original target was a relative path, we want to leave it as relative if it did not require - // globbing to resolve. - if (WildcardPattern.ContainsWildcardCharacters(targetPath)) + // If the original target was a relative path, we want to leave it as relative + if (targetPath.StartsWith('.')) + { + var sessionState = ExecutionContext.EngineSessionState; + string resolvedPath = sessionState.NormalizeRelativePath(globbedTarget[0], sessionState.CurrentLocation.ProviderPath); + content = resolvedPath.StartsWith('.') ? resolvedPath : Path.Combine(".", resolvedPath); + } + else { content = globbedTarget[0]; } 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 a9a2599891b..1a20f478252 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -34,16 +34,17 @@ function Clean-State Describe "New-Item" -Tags "CI" { $tmpDirectory = $TestDrive $testfile = "testfile.txt" + $testfileSp = "``[test``]file.txt" $testfolder = "newDirectory" $testsubfolder = "newSubDirectory" $testlink = "testlink" $FullyQualifiedFile = Join-Path -Path $tmpDirectory -ChildPath $testfile + $FullyQualifiedFileSp = Join-Path -Path $tmpDirectory -ChildPath $testfileSp $FullyQualifiedFolder = Join-Path -Path $tmpDirectory -ChildPath $testfolder $FullyQualifiedLink = Join-Path -Path $tmpDirectory -ChildPath $testlink $FullyQualifiedSubFolder = Join-Path -Path $FullyQualifiedFolder -ChildPath $testsubfolder $FullyQualifiedFileInFolder = Join-Path -Path $FullyQualifiedFolder -ChildPath $testfile - BeforeEach { Clean-State } @@ -103,9 +104,15 @@ Describe "New-Item" -Tags "CI" { Test-Path $FullyQualifiedFile | Should -BeTrue } + It "Should create a file with correct name when Name switch is not used and Path contains special char" { + New-Item -Path $FullyQualifiedFileSp -ItemType file > $null + + $FullyQualifiedFileSp | Should -Exist + } + It "Should be able to create a multiple items in different directories" { $FullyQualifiedFile2 = Join-Path -Path $tmpDirectory -ChildPath test2.txt - New-Item -ItemType file -Path $FullyQualifiedFile, $FullyQualifiedFile2 + New-Item -ItemType file -Path $FullyQualifiedFile, $FullyQualifiedFile2 > $null Test-Path $FullyQualifiedFile | Should -BeTrue Test-Path $FullyQualifiedFile2 | Should -BeTrue @@ -196,9 +203,15 @@ Describe "New-Item with links" -Tags @('CI', 'RequireAdminOnWindows') { $testfile = "testfile.txt" $testfolder = "newDirectory" $testlink = "testlink" + $testlinkSrcSpName = "[test]src" + $testlinkSrcSp = "``[test``]src" + $testlinkSpName = "[test]link" + $testlinkSp = "``[test``]link" $FullyQualifiedFile = Join-Path -Path $tmpDirectory -ChildPath $testfile $FullyQualifiedFolder = Join-Path -Path $tmpDirectory -ChildPath $testfolder $FullyQualifiedLink = Join-Path -Path $tmpDirectory -ChildPath $testlink + $FullyQualifiedLSrcSp = Join-Path -Path $tmpDirectory -ChildPath $testlinkSrcSp + $FullyQualifiedLinkSp = Join-Path -Path $tmpDirectory -ChildPath $testlinkSp $SymLinkMask = [System.IO.FileAttributes]::ReparsePoint $DirLinkMask = $SymLinkMask -bor [System.IO.FileAttributes]::Directory @@ -249,6 +262,21 @@ Describe "New-Item with links" -Tags @('CI', 'RequireAdminOnWindows') { Test-Path $FullyQualifiedLink | Should -BeFalse } + It "Should create symbolic link with name contains special char" { + New-Item -Path $tmpDirectory -Name $testlinkSrcSpName -ItemType File > $null + $FullyQualifiedLSrcSp | Should -Exist + + New-Item -Path $FullyQualifiedLinkSp -Target $FullyQualifiedLSrcSp -ItemType SymbolicLink > $null + $FullyQualifiedLinkSp | Should -Exist + + $expectedTarget = Join-Path -Path $tmpDirectory -ChildPath $testlinkSrcSpName + + $fileInfo = Get-Item -Path $FullyQualifiedLinkSp + $fileInfo.Target | Should -BeExactly $expectedTarget + $fileInfo.LinkType | Should -BeExactly "SymbolicLink" + $fileInfo.Attributes -band $DirLinkMask | Should -BeExactly $SymLinkMask + } + It "New-Item -ItemType SymbolicLink should understand directory path ending with slash" { $folderName = [System.IO.Path]::GetRandomFileName() $symbolicLinkPath = New-Item -ItemType SymbolicLink -Path "$tmpDirectory/$folderName/" -Value "/bar/" diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Remove-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Remove-Item.Tests.ps1 index 5dcb6b9201b..7793c95f03c 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Remove-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Remove-Item.Tests.ps1 @@ -1,9 +1,12 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. Describe "Remove-Item" -Tags "CI" { - $testpath = $TestDrive - $testfile = "testfile.txt" - $testfilepath = Join-Path -Path $testpath -ChildPath $testfile + $testpath = $TestDrive + $testfile = "testfile.txt" + $testfileSpName = "[testfile].txt" + $testfileSp = "``[testfile``].txt" + $testfilepath = Join-Path -Path $testpath -ChildPath $testfile + $testfilepathSp = Join-Path -Path $testpath -ChildPath $testfileSp Context "File removal Tests" { BeforeEach { New-Item -Name $testfile -Path $testpath -ItemType "file" -Value "lorem ipsum" -Force @@ -109,6 +112,14 @@ Describe "Remove-Item" -Tags "CI" { Test-Path (Join-Path -Path $testpath -ChildPath file1.wav) | Should -BeFalse Test-Path (Join-Path -Path $testpath -ChildPath file2.wav) | Should -BeFalse } + + It "Should be able to remove file when path contains special char" { + New-Item -Path $testpath -Name $testfileSpName -ItemType File -Force > $null + $testfilepathSp | Should -Exist + + Remove-Item -Path $testfilepathSp -Force + $testfilepathSp | Should -Not -Exist + } } Context "Directory Removal Tests" {