diff --git a/docs/third-party-licenses.json b/docs/third-party-licenses.json index be1a87d3a..4be471676 100644 --- a/docs/third-party-licenses.json +++ b/docs/third-party-licenses.json @@ -236,5 +236,12 @@ "spdx": "BlueOak-1.0.0", "url": "https://github.com/isaacs/node-glob", "license": "https://github.com/isaacs/node-glob/blob/main/LICENSE.md" + }, + { + "name": "shell-quote", + "version": "1.8.3", + "spdx": "MIT", + "url": "https://github.com/ljharb/shell-quote", + "license": "https://github.com/ljharb/shell-quote/blob/main/LICENSE" } ] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index fa3ee8b09..e9da4316b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "react-window": "^1.8.11", "sax-ts": "^1.2.13", "semver": "^7.7.4", + "shell-quote": "^1.8.3", "tcp-port-used": "^1.0.2", "vscode-jsonrpc": "^8.2.1", "vscode-messenger": "~0.6.0", @@ -70,6 +71,7 @@ "@types/react-dom": "^18.3.1", "@types/react-window": "^1.8.8", "@types/semver": "^7.7.1", + "@types/shell-quote": "^1.7.5", "@types/targz": "^1.0.5", "@types/tcp-port-used": "^1.0.4", "@types/vscode": "^1.63.0", @@ -7038,6 +7040,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/shell-quote": { + "version": "1.7.5", + "integrity": "sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", @@ -21991,7 +21999,6 @@ "node_modules/shell-quote": { "version": "1.8.3", "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index 7743f4705..01e3af697 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "react-window": "^1.8.11", "sax-ts": "^1.2.13", "semver": "^7.7.4", + "shell-quote": "^1.8.3", "tcp-port-used": "^1.0.2", "vscode-jsonrpc": "^8.2.1", "vscode-messenger": "~0.6.0", @@ -133,6 +134,7 @@ "@types/react-dom": "^18.3.1", "@types/react-window": "^1.8.8", "@types/semver": "^7.7.1", + "@types/shell-quote": "^1.7.5", "@types/targz": "^1.0.5", "@types/tcp-port-used": "^1.0.4", "@types/vscode": "^1.63.0", diff --git a/src/views/solution-outline/commands/merge-command.ts b/src/views/solution-outline/commands/merge-command.ts index 9056e9b05..f8ddbc6e0 100644 --- a/src/views/solution-outline/commands/merge-command.ts +++ b/src/views/solution-outline/commands/merge-command.ts @@ -23,6 +23,7 @@ import path from 'path'; import * as os from 'os'; import * as fs from 'fs'; import { ActiveSolutionTracker } from '../../../solutions/active-solution-tracker'; +import { quote as shellQuote } from 'shell-quote'; export class MergeCommand { public static readonly mergeFile = `${PACKAGE_NAME}.mergeFile`; @@ -89,10 +90,8 @@ export class MergeCommand { mergedMTimeBefore = fs.statSync(merged).mtimeMs; } - const command = `"${codePath}" --wait --merge "${local}" "${update}" "${base}" "${merged}"`; - try { - const exitCode = await this.doOpen3WayMerge(command); + const exitCode = await this.doOpen3WayMerge([ codePath, '--wait', '--merge', local, update, base, merged ]); // get the modification time after merge let mergedMTimeAfter = 0; @@ -183,11 +182,12 @@ export class MergeCommand { return undefined; } - private doOpen3WayMerge(command: string): Promise { + private doOpen3WayMerge(command: string[]): Promise { + const args = shellQuote(command); return new Promise((resolve, reject) => { - exec(command, (error: ExecException | null) => { + exec(args, (error: ExecException | null) => { if (error) { - console.error(`Error executing command: ${command}`, error); + console.error(`Error executing command: ${args}`, error); if (typeof error.code === 'number') { resolve(error.code);