Skip to content

Commit 9d8f2dc

Browse files
fix: Shellexec args escaping on Windows
1 parent 1d4e208 commit 9d8f2dc

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

lib/utils.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import _ from 'lodash';
2-
import { util, net } from 'appium/support';
2+
import { net } from 'appium/support';
33
import { promisify } from 'node:util';
44
import { exec } from 'node:child_process';
55
import B from 'bluebird';
@@ -21,7 +21,7 @@ export async function shellExec(cmd, args = [], opts = {}) {
2121
const {
2222
timeoutMs = 60 * 1000 * 5
2323
} = opts;
24-
const fullCmd = util.quote([cmd, ...args]);
24+
const fullCmd = [cmd, ...args].map(escapeWindowsArg).join(' ');
2525
const { stdout, stderr } = await B.resolve(execAsync(fullCmd, opts))
2626
.timeout(timeoutMs, `The command '${fullCmd}' timed out after ${timeoutMs}ms`);
2727
return {
@@ -30,6 +30,27 @@ export async function shellExec(cmd, args = [], opts = {}) {
3030
};
3131
}
3232

33+
/**
34+
* Escapes a string to be used as a Windows command line argument
35+
*
36+
* @param {string} arg
37+
* @returns {string}
38+
*/
39+
function escapeWindowsArg(arg) {
40+
if (!arg) {
41+
return '""';
42+
}
43+
44+
const needsQuotes = /[\s"]/g.test(arg);
45+
if (!needsQuotes) {
46+
return arg;
47+
}
48+
49+
// Escape double quotes and backslashes before quotes
50+
const escaped = arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, '$1$1');
51+
return `"${escaped}"`;
52+
}
53+
3354
/**
3455
*
3556
* @param {string} srcUrl

0 commit comments

Comments
 (0)