From 2ccf79c6e0c5029f52766ff0e94312d60edb4f54 Mon Sep 17 00:00:00 2001 From: Eduardo Speroni Date: Thu, 25 Jul 2024 12:40:17 -0300 Subject: [PATCH] fix: quote windows command line arguments --- lib/base-package-manager.ts | 20 +++++++++++++------ .../android/android-virtual-device-service.ts | 7 +++++-- lib/services/android-plugin-build-service.ts | 7 +++++-- .../android/gradle-command-service.ts | 6 +++++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lib/base-package-manager.ts b/lib/base-package-manager.ts index 12b24df7d1..86e40c8ea9 100644 --- a/lib/base-package-manager.ts +++ b/lib/base-package-manager.ts @@ -1,4 +1,4 @@ -import { isInteractive } from "./common/helpers"; +import { isInteractive, quoteString } from "./common/helpers"; import { INodePackageManager, INodePackageManagerInstallOptions, @@ -108,11 +108,19 @@ export abstract class BasePackageManager implements INodePackageManager { ): Promise { const npmExecutable = this.getPackageManagerExecutableName(); const stdioValue = isInteractive() ? "inherit" : "pipe"; - await this.$childProcess.spawnFromEvent(npmExecutable, params, "close", { - cwd: opts.cwd, - stdio: stdioValue, - shell: this.$hostInfo.isWindows, - }); + const sanitizedNpmExecutable = this.$hostInfo.isWindows + ? quoteString(npmExecutable) + : npmExecutable; + await this.$childProcess.spawnFromEvent( + sanitizedNpmExecutable, + params, + "close", + { + cwd: opts.cwd, + stdio: stdioValue, + shell: this.$hostInfo.isWindows, + } + ); // Whenever calling "npm install" or "yarn add" without any arguments (hence installing all dependencies) no output is emitted on stdout // Luckily, whenever you call "npm install" or "yarn add" to install all dependencies chances are you won't need the name/version of the package you're installing because there is none. diff --git a/lib/common/mobile/android/android-virtual-device-service.ts b/lib/common/mobile/android/android-virtual-device-service.ts index ade98318dc..d6b58f2339 100644 --- a/lib/common/mobile/android/android-virtual-device-service.ts +++ b/lib/common/mobile/android/android-virtual-device-service.ts @@ -9,7 +9,7 @@ import { NOT_RUNNING_EMULATOR_STATUS, } from "../../constants"; import { cache } from "../../decorators"; -import { settlePromises } from "../../helpers"; +import { quoteString, settlePromises } from "../../helpers"; import { DeviceConnectionType } from "../../../constants"; import { IStringDictionary, @@ -221,8 +221,11 @@ export class AndroidVirtualDeviceService } if (canExecuteAvdManagerCommand) { + const sanitizedPathToAvdManagerExecutable = this.$hostInfo.isWindows + ? quoteString(this.pathToAvdManagerExecutable) + : this.pathToAvdManagerExecutable; result = await this.$childProcess.trySpawnFromCloseEvent( - this.pathToAvdManagerExecutable, + sanitizedPathToAvdManagerExecutable, ["list", "avds"], { shell: this.$hostInfo.isWindows } ); diff --git a/lib/services/android-plugin-build-service.ts b/lib/services/android-plugin-build-service.ts index 9e525e4ba0..77cda49684 100644 --- a/lib/services/android-plugin-build-service.ts +++ b/lib/services/android-plugin-build-service.ts @@ -8,7 +8,7 @@ import { PLUGIN_BUILD_DATA_FILENAME, SCOPED_ANDROID_RUNTIME_NAME, } from "../constants"; -import { getShortPluginName, hook } from "../common/helpers"; +import { getShortPluginName, hook, quoteString } from "../common/helpers"; import { Builder, parseString } from "xml2js"; import { IRuntimeGradleVersions, @@ -841,9 +841,12 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService { } try { + const sanitizedArgs = this.$hostInfo.isWindows + ? localArgs.map((arg) => quoteString(arg)) + : localArgs; await this.$childProcess.spawnFromEvent( gradlew, - localArgs, + sanitizedArgs, "close", opts ); diff --git a/lib/services/android/gradle-command-service.ts b/lib/services/android/gradle-command-service.ts index 3e6c3e3117..bca2282bd7 100644 --- a/lib/services/android/gradle-command-service.ts +++ b/lib/services/android/gradle-command-service.ts @@ -10,6 +10,7 @@ import { IGradleCommandOptions, } from "../../definitions/gradle"; import { injector } from "../../common/yok"; +import { quoteString } from "../../common/helpers"; export class GradleCommandService implements IGradleCommandService { constructor( @@ -35,9 +36,12 @@ export class GradleCommandService implements IGradleCommandService { options.gradlePath ?? (this.$hostInfo.isWindows ? "gradlew.bat" : "./gradlew"); + const sanitizedGradleArgs = this.$hostInfo.isWindows + ? gradleArgs.map((arg) => quoteString(arg)) + : gradleArgs; const result = await this.executeCommandSafe( gradleExecutable, - gradleArgs, + sanitizedGradleArgs, childProcessOptions, spawnOptions );