Fix Rename-Item to allow Unix globbing patterns in paths (#2799) (#3661)

* Fix Rename-Item to allow Unix globbing patterns in -Literal paths (#2799)

In the process of normalizing a relative path, PowerShell checks to see
see if the path exists, which it does by invoking
    Directory.EnumerateFiles(directory, filename);

On Unix platforms, if the filename contains globbing patterns, such as [ab],
EnumerateFiles (and EnumerateDirectories) will perform the globbing. Using
globbing patterns, a file named 'file[txt].txt' is reported as not existing.

This fix changes the file-existence test on Unix to use a native function
instead of either of the Directory.EnumerateXXX functions.

* Fix for AppVeyor failure

* Changes per code review, and a couple of letter-casing changes.
This commit is contained in:
jeffbi
2017-05-02 18:42:16 -07:00
committed by Mike Richmond
parent 0187d9e110
commit 2a739afa9c
2 changed files with 61 additions and 0 deletions
@@ -4953,6 +4953,23 @@ namespace Microsoft.PowerShell.Commands
return String.Empty;
}
#if UNIX
// We don't use the Directory class for Unix because the path
// may contain additional globbing patterns such as '[ab]'
// which Directory.EnumerateFiles() processes, giving undesireable
// results in this context.
if (!Utils.NativeItemExists(result))
{
String error = StringUtil.Format(FileSystemProviderStrings.ItemDoesNotExist, path);
Exception e = new IOException(error);
WriteError(new ErrorRecord(
e,
"ItemDoesNotExist",
ErrorCategory.ObjectNotFound,
path));
break;
}
#else
string leafName = GetChildName(result);
// Use the Directory class to get the real path (this will
@@ -4978,6 +4995,7 @@ namespace Microsoft.PowerShell.Commands
}
result = files.First();
#endif
if (result.StartsWith(basePath, StringComparison.CurrentCulture))
{
@@ -246,6 +246,49 @@ Describe "Basic FileSystem Provider Tests" -Tags "CI" {
}
}
Describe "Handling of globbing patterns" -Tags "CI" {
Context "Handling of Unix [ab] globbing patterns in literal paths" {
BeforeAll {
$filePath = Join-Path $TESTDRIVE "file[txt].txt"
$newPath = Join-Path $TESTDRIVE "file.txt.txt"
$dirPath = Join-Path $TESTDRIVE "subdir"
}
BeforeEach {
$file = New-Item -ItemType File -Path $filePath -Force
}
AfterEach
{
Remove-Item -Force -Recurse -Path $dirPath -ErrorAction SilentlyContinue
Remove-Item -Force -LiteralPath $newPath -ErrorAction SilentlyContinue
}
It "Rename-Item -LiteralPath can rename a file with Unix globbing characters" {
Rename-Item -LiteralPath $file.FullName -NewName $newPath
Test-Path -LiteralPath $file.FullName | Should Be $false
Test-Path -LiteralPath $newPath | Should Be $true
}
It "Remove-Item -LiteralPath can delete a file with Unix globbing characters" {
Remove-Item -LiteralPath $file.FullName
Test-Path -LiteralPath $file.FullName | Should Be $false
}
It "Move-Item -LiteralPath can move a file with Unix globbing characters" {
$dir = New-Item -ItemType Directory -Path $dirPath
Move-Item -LiteralPath $file.FullName -Destination $dir.FullName
Test-Path -LiteralPath $file.FullName | Should Be $false
$newPath = Join-Path $dir.FullName $file.Name
Test-Path -LiteralPath $newPath | Should Be $true
}
It "Copy-Item -LiteralPath can copy a file with Unix globbing characters" {
Copy-Item -LiteralPath $file.FullName -Destination $newPath
Test-Path -LiteralPath $newPath | Should Be $true
}
}
}
Describe "Hard link and symbolic link tests" -Tags "CI", "RequireAdminOnWindows" {
BeforeAll {
# on macOS, the /tmp directory is a symlink, so we'll resolve it here