Skip to content

Commit 0380034

Browse files
authored
Quote bare quote file paths if the path includes a double quote character (PowerShell#25631)
1 parent a2b11b2 commit 0380034

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5043,14 +5043,24 @@ private static void EscapeCharIfNeeded(
50435043
break;
50445044

50455045
default:
5046-
// Handle all the different quote types
5047-
if (useSingleQuoteEscapeRules && path[index].IsSingleQuote())
5046+
if (useSingleQuoteEscapeRules)
50485047
{
5049-
_ = sb.Append('\'');
5050-
quotesAreNeeded = true;
5048+
// Bareword or singlequoted input string.
5049+
if (path[index].IsSingleQuote())
5050+
{
5051+
// SingleQuotes are escaped with more single quotes. quotesAreNeeded is set so bareword strings can quoted.
5052+
_ = sb.Append('\'');
5053+
quotesAreNeeded = true;
5054+
}
5055+
else if (!quotesAreNeeded && stringType == StringConstantType.BareWord && path[index].IsDoubleQuote())
5056+
{
5057+
// Bareword string with double quote inside. Make sure to quote it so we don't need to escape it.
5058+
quotesAreNeeded = true;
5059+
}
50515060
}
5052-
else if (!useSingleQuoteEscapeRules && path[index].IsDoubleQuote())
5061+
else if (path[index].IsDoubleQuote())
50535062
{
5063+
// Double quoted or bareword with variables input string. Need to escape double quotes.
50545064
_ = sb.Append('`');
50555065
quotesAreNeeded = true;
50565066
}

test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2257,6 +2257,42 @@ param ($Param1)
22572257

22582258
Remove-Item -LiteralPath $LiteralPath
22592259
}
2260+
2261+
It "Should add single quotes if there are double quotes in bare word file path" {
2262+
$BadQuote = [char]8220
2263+
$TestFile1 = Join-Path -Path $TestDrive -ChildPath "Test1${BadQuote}File"
2264+
$null = New-Item -Path $TestFile1 -Force
2265+
$res = TabExpansion2 -inputScript "Get-ChildItem -Path $TestDrive\"
2266+
($res.CompletionMatches | Where-Object ListItemText -Like "Test1?File").CompletionText | Should -Be "'$TestFile1'"
2267+
Remove-Item -LiteralPath $TestFile1 -Force
2268+
}
2269+
2270+
It "Should escape double quote if the input string uses double quotes" {
2271+
$BadQuote = [char]8220
2272+
$TestFile1 = Join-Path -Path $TestDrive -ChildPath "Test1${BadQuote}File"
2273+
$null = New-Item -Path $TestFile1 -Force
2274+
$res = TabExpansion2 -inputScript "Get-ChildItem -Path `"$TestDrive\"
2275+
$Expected = "`"$($TestFile1.Insert($TestFile1.LastIndexOf($BadQuote), '`'))`""
2276+
($res.CompletionMatches | Where-Object ListItemText -Like "Test1?File").CompletionText | Should -Be $Expected
2277+
Remove-Item -LiteralPath $TestFile1 -Force
2278+
}
2279+
2280+
It "Should escape single quotes in file paths" {
2281+
$SingleQuote = "'"
2282+
$TestFile1 = Join-Path -Path $TestDrive -ChildPath "Test1${SingleQuote}File"
2283+
$null = New-Item -Path $TestFile1 -Force
2284+
# Regardless if the input string was singlequoted or not, we expect to add surrounding single quotes and
2285+
# escape the single quote in the file path with another singlequote.
2286+
$Expected = "'$($TestFile1.Insert($TestFile1.LastIndexOf($SingleQuote), "'"))'"
2287+
2288+
$res = TabExpansion2 -inputScript "Get-ChildItem -Path '$TestDrive\"
2289+
($res.CompletionMatches | Where-Object ListItemText -Like "Test1?File").CompletionText | Should -Be $Expected
2290+
2291+
$res = TabExpansion2 -inputScript "Get-ChildItem -Path $TestDrive\"
2292+
($res.CompletionMatches | Where-Object ListItemText -Like "Test1?File").CompletionText | Should -Be $Expected
2293+
2294+
Remove-Item -LiteralPath $TestFile1 -Force
2295+
}
22602296
}
22612297

22622298
It 'Should correct slashes in UNC path completion' -Skip:(!$IsWindows) {

0 commit comments

Comments
 (0)