Fix Rename-Item -Path with wildcard char (#7398)

This commit is contained in:
kwkam 2018-11-10 03:08:26 +08:00 committed by Aditya Patwardhan
parent 4118fd2829
commit caad7ed471
4 changed files with 124 additions and 12 deletions

View file

@ -3519,22 +3519,87 @@ namespace Microsoft.PowerShell.Commands
#region Command code
private Collection<PathInfo> GetResolvedPaths(string path)
{
Collection<PathInfo> results = null;
try
{
results = SessionState.Path.GetResolvedPSPathFromPSPath(path, CmdletProviderContext);
}
catch (PSNotSupportedException notSupported)
{
WriteError(
new ErrorRecord(
notSupported.ErrorRecord,
notSupported));
}
catch (DriveNotFoundException driveNotFound)
{
WriteError(
new ErrorRecord(
driveNotFound.ErrorRecord,
driveNotFound));
}
catch (ProviderNotFoundException providerNotFound)
{
WriteError(
new ErrorRecord(
providerNotFound.ErrorRecord,
providerNotFound));
}
catch (ItemNotFoundException pathNotFound)
{
WriteError(
new ErrorRecord(
pathNotFound.ErrorRecord,
pathNotFound));
}
return results;
}
/// <summary>
/// Moves the specified item to the specified destination
/// </summary>
protected override void ProcessRecord()
{
if (SuppressWildcardExpansion)
{
RenameItem(Path, literalPath: true);
return;
}
Collection<PathInfo> resolvedPaths = GetResolvedPaths(Path);
if (resolvedPaths == null)
{
return;
}
if (resolvedPaths.Count == 1)
{
RenameItem(resolvedPaths[0].Path, literalPath: true);
}
else
{
RenameItem(WildcardPattern.Unescape(Path), literalPath: true);
}
}
private void RenameItem(string path, bool literalPath = false)
{
CmdletProviderContext currentContext = CmdletProviderContext;
currentContext.SuppressWildcardExpansion = literalPath;
try
{
if (!InvokeProvider.Item.Exists(Path, currentContext))
if (!InvokeProvider.Item.Exists(path, currentContext))
{
PSInvalidOperationException invalidOperation =
(PSInvalidOperationException)
PSTraceSource.NewInvalidOperationException(
NavigationResources.RenameItemDoesntExist,
Path);
path);
WriteError(
new ErrorRecord(
@ -3580,7 +3645,7 @@ namespace Microsoft.PowerShell.Commands
bool isCurrentLocationOrAncestor = false;
try
{
isCurrentLocationOrAncestor = SessionState.Path.IsCurrentLocationOrAncestor(_path, currentContext);
isCurrentLocationOrAncestor = SessionState.Path.IsCurrentLocationOrAncestor(path, currentContext);
}
catch (PSNotSupportedException notSupported)
{
@ -3621,7 +3686,7 @@ namespace Microsoft.PowerShell.Commands
(PSInvalidOperationException)
PSTraceSource.NewInvalidOperationException(
NavigationResources.RenamedItemInUse,
Path);
path);
WriteError(
new ErrorRecord(
@ -3635,12 +3700,12 @@ namespace Microsoft.PowerShell.Commands
currentContext.PassThru = PassThru;
tracer.WriteLine("Rename {0} to {1}", Path, NewName);
tracer.WriteLine("Rename {0} to {1}", path, NewName);
try
{
// Now do the rename
InvokeProvider.Item.Rename(Path, NewName, currentContext);
InvokeProvider.Item.Rename(path, NewName, currentContext);
}
catch (PSNotSupportedException notSupported)
{
@ -3674,7 +3739,7 @@ namespace Microsoft.PowerShell.Commands
pathNotFound));
return;
}
} // ProcessRecord
}
#endregion Command code
} // RenameItemCommand

View file

@ -433,7 +433,13 @@ namespace System.Management.Automation
s_pathResolutionTracer.WriteLine("Path is DRIVE-QUALIFIED");
string relativePath = GetDriveRootRelativePathFromPSPath(path, context, true, out drive, out providerInstance);
string relativePath =
GetDriveRootRelativePathFromPSPath(
path,
context,
!context.SuppressWildcardExpansion,
out drive,
out providerInstance);
Dbg.Diagnostics.Assert(
drive != null,

View file

@ -104,7 +104,7 @@ Describe "Basic Function Provider Tests" -Tags "CI" {
}
It "Fails to rename not existing function" {
{ Rename-Item $nonExistingFunction -NewName $newName -ErrorAction Stop } | Should -Throw -ErrorId "InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand"
{ Rename-Item $nonExistingFunction -NewName $newName -ErrorAction Stop } | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.RenameItemCommand"
}
It "Fails to rename function which is Constant" {
@ -113,8 +113,8 @@ Describe "Basic Function Provider Tests" -Tags "CI" {
}
It "Fails to rename function which is ReadOnly" {
Set-Item $nonExistingFunction -Options "ReadOnly"
{ Rename-Item $nonExistingFunction -NewName $newName -ErrorAction Stop } | Should -Throw -ErrorId "InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand"
Set-Item $nonExistingFunction -Options "ReadOnly" -Value $functionValue
{ Rename-Item $nonExistingFunction -NewName $newName -ErrorAction Stop } | Should -Throw -ErrorId "CannotRenameFunction,Microsoft.PowerShell.Commands.RenameItemCommand"
}
It "Renames ReadOnly function when -Force parameter is on" {

View file

@ -2,10 +2,15 @@
# Licensed under the MIT License.
Describe "Rename-Item tests" -Tag "CI" {
BeforeAll {
$content = "This is content"
Setup -f originalFile.txt -content "This is content"
$source = "$TESTDRIVE/originalFile.txt"
$target = "$TESTDRIVE/ItemWhichHasBeenRenamed.txt"
Setup -f [orig-file].txt -content "This is not content"
$sourceSp = "$TestDrive/``[orig-file``].txt"
$targetSpName = "ItemWhichHasBeen[Renamed].txt"
$targetSp = "$TestDrive/ItemWhichHasBeen``[Renamed``].txt"
Setup -Dir [test-dir]
$wdSp = "$TestDrive/``[test-dir``]"
}
It "Rename-Item will rename a file" {
Rename-Item $source $target
@ -13,4 +18,40 @@ Describe "Rename-Item tests" -Tag "CI" {
test-path $target | Should -BeTrue
"$target" | Should -FileContentMatchExactly "This is content"
}
It "Rename-Item will rename a file when path contains special char" {
Rename-Item $sourceSp $targetSpName
$sourceSp | Should -Not -Exist
$targetSp | Should -Exist
$targetSp | Should -FileContentMatchExactly "This is not content"
}
It "Rename-Item will rename a file when -Path and CWD contains special char" {
$content = "This is content"
$oldSpName = "[orig]file.txt"
$oldSpBName = "``[orig``]file.txt"
$oldSp = "$wdSp/$oldSpBName"
$newSpName = "[renamed]file.txt"
$newSp = "$wdSp/``[renamed``]file.txt"
In $wdSp -Execute {
$null = New-Item -Name $oldSpName -ItemType File -Value $content -Force
Rename-Item -Path $oldSpBName $newSpName
}
$oldSp | Should -Not -Exist
$newSp | Should -Exist
$newSp | Should -FileContentMatchExactly $content
}
It "Rename-Item will rename a file when -LiteralPath and CWD contains special char" {
$content = "This is not content"
$oldSpName = "[orig]file2.txt"
$oldSpBName = "``[orig``]file2.txt"
$oldSp = "$wdSp/$oldSpBName"
$newSpName = "[renamed]file2.txt"
$newSp = "$wdSp/``[renamed``]file2.txt"
In $wdSp -Execute {
$null = New-Item -Name $oldSpName -ItemType File -Value $content -Force
Rename-Item -LiteralPath $oldSpName $newSpName
}
$oldSp | Should -Not -Exist
$newSp | Should -Exist
$newSp | Should -FileContentMatchExactly $content
}
}