Skip to content
This repository was archived by the owner on Apr 20, 2023. It is now read-only.

Commit ba8e18d

Browse files
Nate McMasterPeter Huene
authored andcommitted
Fix #4139 - escape quoted strings for process start
1 parent 9cc2b7c commit ba8e18d

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,6 @@ private static string EscapeArgForCmd(string argument)
185185

186186
internal static bool ShouldSurroundWithQuotes(string argument)
187187
{
188-
// Don't quote already quoted strings
189-
if (IsSurroundedWithQuotes(argument))
190-
{
191-
return false;
192-
}
193-
194188
// Only quote if whitespace exists in the string
195189
return ArgumentContainsWhitespace(argument);
196190
}

src/Microsoft.DotNet.Cli.Utils/CommandResolution/WindowsExePreferredCommandSpecFactory.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ private CommandSpec CreateCommandSpecWrappedWithCmd(
6363

6464
var cmdEscapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForCmdProcessStart(args);
6565

66-
if (ArgumentEscaper.ShouldSurroundWithQuotes(command))
66+
if (!ArgumentEscaper.IsSurroundedWithQuotes(command) // Don't quote already quoted strings
67+
&& ArgumentEscaper.ShouldSurroundWithQuotes(command))
6768
{
6869
command = $"\"{command}\"";
6970
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using Xunit;
5+
6+
namespace Microsoft.DotNet.Cli.Utils.Tests
7+
{
8+
public class ArgumentEscaperTests
9+
{
10+
[Theory]
11+
[InlineData(new[] { "one", "two", "three" }, "one two three")]
12+
[InlineData(new[] { "line1\nline2", "word1\tword2" }, "\"line1\nline2\" \"word1\tword2\"")]
13+
[InlineData(new[] { "with spaces" }, "\"with spaces\"")]
14+
[InlineData(new[] { @"with\backslash" }, @"with\backslash")]
15+
[InlineData(new[] { @"""quotedwith\backslash""" }, @"\""quotedwith\backslash\""")]
16+
[InlineData(new[] { @"C:\Users\" }, @"C:\Users\")]
17+
[InlineData(new[] { @"C:\Program Files\dotnet\" }, @"""C:\Program Files\dotnet\\""")]
18+
[InlineData(new[] { @"backslash\""preceedingquote" }, @"backslash\\\""preceedingquote")]
19+
[InlineData(new[] { @""" hello """ }, @"""\"" hello \""""")]
20+
public void EscapesArgumentsForProcessStart(string[] args, string expected)
21+
{
22+
Assert.Equal(expected, ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args));
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)