Skip to content

Commit 8c8a552

Browse files
authored
Some terminal launch config args are double-escaped (microsoft#149380)
Fixes microsoft#149283
1 parent 5b8bd1c commit 8c8a552

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

src/vs/workbench/contrib/debug/node/terminals.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ export function prepareCommand(shell: string, args: string[], cwd?: string, env?
121121
case ShellType.cmd:
122122

123123
quote = (s: string) => {
124+
// Note: Wrapping in cmd /C "..." complicates the escaping.
125+
// cmd /C "node -e "console.log(process.argv)" """A^>0"""" # prints "A>0"
126+
// cmd /C "node -e "console.log(process.argv)" "foo^> bar"" # prints foo> bar
127+
// Outside of the cmd /C, it could be a simple quoting, but here, the ^ is needed too
124128
s = s.replace(/\"/g, '""');
125129
s = s.replace(/([><!^&|])/g, '^$1');
126130
return (' "'.split('').some(char => s.includes(char)) || s.length === 0) ? `"${s}"` : s;
@@ -157,8 +161,8 @@ export function prepareCommand(shell: string, args: string[], cwd?: string, env?
157161
case ShellType.bash: {
158162

159163
quote = (s: string) => {
160-
s = s.replace(/(["'\\\$!><#()\[\]*&^|])/g, '\\$1');
161-
return (' ;'.split('').some(char => s.includes(char)) || s.length === 0) ? `"${s}"` : s;
164+
s = s.replace(/(["'\\\$!><#()\[\]*&^| ;])/g, '\\$1');
165+
return s.length === 0 ? `""` : s;
162166
};
163167

164168
const hardQuote = (s: string) => {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as assert from 'assert';
7+
import { prepareCommand } from 'vs/workbench/contrib/debug/node/terminals';
8+
9+
10+
suite('Debug - prepareCommand', () => {
11+
test('bash', () => {
12+
assert.strictEqual(
13+
prepareCommand('bash', ['{$} (']).trim(),
14+
'{\\$}\\ \\(');
15+
assert.strictEqual(
16+
prepareCommand('bash', ['hello', 'world', '--flag=true']).trim(),
17+
'hello world --flag=true');
18+
assert.strictEqual(
19+
prepareCommand('bash', [' space arg ']).trim(),
20+
'\\ space\\ arg\\');
21+
});
22+
23+
test('bash - do not escape > and <', () => {
24+
assert.strictEqual(
25+
prepareCommand('bash', ['arg1', '>', '> hello.txt', '<', '<input.in']).trim(),
26+
'arg1 > \\>\\ hello.txt < \\<input.in');
27+
});
28+
29+
test('cmd', () => {
30+
assert.strictEqual(
31+
prepareCommand('cmd.exe', ['^!< ']).trim(),
32+
'"^^^!^< "');
33+
assert.strictEqual(
34+
prepareCommand('cmd.exe', ['hello', 'world', '--flag=true']).trim(),
35+
'hello world --flag=true');
36+
assert.strictEqual(
37+
prepareCommand('cmd.exe', [' space arg ']).trim(),
38+
'" space arg "');
39+
assert.strictEqual(
40+
prepareCommand('cmd.exe', ['"A>0"']).trim(),
41+
'"""A^>0"""');
42+
assert.strictEqual(
43+
prepareCommand('cmd.exe', ['']).trim(),
44+
'""');
45+
});
46+
47+
test('cmd - do not escape > and <', () => {
48+
assert.strictEqual(
49+
prepareCommand('cmd.exe', ['arg1', '>', '> hello.txt', '<', '<input.in']).trim(),
50+
'arg1 > "^> hello.txt" < ^<input.in');
51+
});
52+
53+
test('powershell', () => {
54+
assert.strictEqual(
55+
prepareCommand('powershell', ['!< ']).trim(),
56+
`& '!< '`);
57+
assert.strictEqual(
58+
prepareCommand('powershell', ['hello', 'world', '--flag=true']).trim(),
59+
`& 'hello' 'world' '--flag=true'`);
60+
assert.strictEqual(
61+
prepareCommand('powershell', [' space arg ']).trim(),
62+
`& ' space arg '`);
63+
assert.strictEqual(
64+
prepareCommand('powershell', ['"A>0"']).trim(),
65+
`& '"A>0"'`);
66+
assert.strictEqual(
67+
prepareCommand('powershell', ['']).trim(),
68+
`& ''`);
69+
});
70+
71+
test('powershell - do not escape > and <', () => {
72+
assert.strictEqual(
73+
prepareCommand('powershell', ['arg1', '>', '> hello.txt', '<', '<input.in']).trim(),
74+
`& 'arg1' > '> hello.txt' < '<input.in'`);
75+
});
76+
});

0 commit comments

Comments
 (0)