From 59311d03e16688d336ecc8758d2167643406b06c Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Wed, 11 Oct 2017 07:01:09 -0700 Subject: [PATCH] Properly escape trailing backslash so that it doesn't end up escaping the quotes (#4965) The native command receives the arg ".\test 1" as .\test 1" as the last \" is treated as escaping the quotes. Fix is to add an extra backslash to escape the last enclosing quote. --- .../engine/NativeCommandParameterBinder.cs | 6 ++++++ .../NativeCommandArguments.Tests.ps1 | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs b/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs index c00f62823e..44c298c776 100644 --- a/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs +++ b/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs @@ -196,7 +196,13 @@ namespace System.Management.Automation if (NeedQuotes(arg)) { _arguments.Append('"'); + // need to escape all trailing backslashes so the native command receives it correctly + // according to http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC _arguments.Append(arg); + for (int i = arg.Length-1; i >= 0 && arg[i] == '\\'; i--) + { + _arguments.Append('\\'); + } _arguments.Append('"'); } else diff --git a/test/powershell/Language/Scripting/NativeExecution/NativeCommandArguments.Tests.ps1 b/test/powershell/Language/Scripting/NativeExecution/NativeCommandArguments.Tests.ps1 index aba3637c03..aaa82eb40c 100644 --- a/test/powershell/Language/Scripting/NativeExecution/NativeCommandArguments.Tests.ps1 +++ b/test/powershell/Language/Scripting/NativeExecution/NativeCommandArguments.Tests.ps1 @@ -8,7 +8,7 @@ Describe "Native Command Arguments" -tags "CI" { It "Should handle quoted spaces correctly" { $a = 'a"b c"d' $lines = testexe -echoargs $a 'a"b c"d' a"b c"d - ($lines | measure).Count | Should Be 3 + $lines.Count | Should Be 3 $lines[0] | Should Be 'Arg 0 is ' $lines[1] | Should Be 'Arg 1 is ' $lines[2] | Should Be 'Arg 2 is ' @@ -27,8 +27,20 @@ Describe "Native Command Arguments" -tags "CI" { # looking at how it got the arguments. It "Should handle spaces between escaped quotes" { $lines = testexe -echoargs 'a\"b c\"d' "a\`"b c\`"d" - ($lines | measure).Count | Should Be 2 + $lines.Count | Should Be 2 $lines[0] | Should Be 'Arg 0 is ' $lines[1] | Should Be 'Arg 1 is ' } + + It "Should correctly quote paths with spaces: " -TestCases @( + @{arguments = "'.\test 1\' `".\test 2\`"" ; expected = @(".\test 1\",".\test 2\")}, + @{arguments = "'.\test 1\\\' `".\test 2\\`""; expected = @(".\test 1\\\",".\test 2\\")} + ) { + param($arguments, $expected) + $lines = Invoke-Expression "testexe -echoargs $arguments" + $lines.Count | Should Be $expected.Count + for ($i = 0; $i -lt $lines.Count; $i++) { + $lines[$i] | Should Be "Arg $i is <$($expected[$i])>" + } + } }