Loading libraries/adb/src/commands/subprocess/utils.spec.ts +16 −1 Original line number Diff line number Diff line import * as assert from "node:assert"; import { describe, it } from "node:test"; import { escapeArg } from "./utils.js"; import { escapeArg, splitCommand } from "./utils.js"; describe("escapeArg", () => { it("should escape single quotes", () => { Loading Loading @@ -42,3 +42,18 @@ describe("escapeArg", () => { assert.equal(escapeArg("abc)"), String.raw`'abc)'`); }); }); describe("splitCommand", () => { it("should split command", () => { assert.deepEqual(splitCommand(""), []); assert.deepEqual(splitCommand("abc"), ["abc"]); assert.deepEqual(splitCommand("abc def"), ["abc", "def"]); assert.deepEqual(splitCommand("abc 'def'"), ["abc", "def"]); assert.deepEqual(splitCommand("abc 'def' ghi"), ["abc", "def", "ghi"]); assert.deepEqual(splitCommand("abc 'def' 'ghi'"), [ "abc", "def", "ghi", ]); }); }); libraries/adb/src/commands/subprocess/utils.ts +11 −8 Original line number Diff line number Diff line Loading @@ -26,20 +26,20 @@ export function splitCommand(command: string): string[] { const result: string[] = []; let quote: string | undefined; let isEscaped = false; let start = 0; let value = ""; for (let i = 0, len = command.length; i < len; i += 1) { for (const char of command) { if (isEscaped) { value += char; isEscaped = false; continue; } const char = command.charAt(i); switch (char) { case " ": if (!quote && i !== start) { result.push(command.substring(start, i)); start = i + 1; if (!quote && value) { result.push(value); value = ""; } break; case "'": Loading @@ -53,11 +53,14 @@ export function splitCommand(command: string): string[] { case "\\": isEscaped = true; break; default: value += char; break; } } if (start < command.length) { result.push(command.substring(start)); if (value) { result.push(value); } return result; Loading libraries/android-bin/src/cmd/utils.ts +1 −9 Original line number Diff line number Diff line import { splitCommand } from "@yume-chan/adb"; import type { Cmd } from "./service.js"; export function resolveFallback( Loading Loading @@ -31,13 +29,7 @@ export function serializeAbbService( ): string { checkCommand(command); // `abb` mode doesn't use `sh -c` to execute to command, // so it doesn't accept escaped arguments. // `splitCommand` can be used to remove the escaping, // each item in `command` must be a single argument. const newCommand = command.map((arg) => splitCommand(arg)[0]!); // `abb` mode uses `\0` as the separator, allowing space in arguments. // The last `\0` is required for older versions of `adb`. return `${prefix}:${newCommand.join("\0")}\0`; return `${prefix}:${command.join("\0")}\0`; } Loading
libraries/adb/src/commands/subprocess/utils.spec.ts +16 −1 Original line number Diff line number Diff line import * as assert from "node:assert"; import { describe, it } from "node:test"; import { escapeArg } from "./utils.js"; import { escapeArg, splitCommand } from "./utils.js"; describe("escapeArg", () => { it("should escape single quotes", () => { Loading Loading @@ -42,3 +42,18 @@ describe("escapeArg", () => { assert.equal(escapeArg("abc)"), String.raw`'abc)'`); }); }); describe("splitCommand", () => { it("should split command", () => { assert.deepEqual(splitCommand(""), []); assert.deepEqual(splitCommand("abc"), ["abc"]); assert.deepEqual(splitCommand("abc def"), ["abc", "def"]); assert.deepEqual(splitCommand("abc 'def'"), ["abc", "def"]); assert.deepEqual(splitCommand("abc 'def' ghi"), ["abc", "def", "ghi"]); assert.deepEqual(splitCommand("abc 'def' 'ghi'"), [ "abc", "def", "ghi", ]); }); });
libraries/adb/src/commands/subprocess/utils.ts +11 −8 Original line number Diff line number Diff line Loading @@ -26,20 +26,20 @@ export function splitCommand(command: string): string[] { const result: string[] = []; let quote: string | undefined; let isEscaped = false; let start = 0; let value = ""; for (let i = 0, len = command.length; i < len; i += 1) { for (const char of command) { if (isEscaped) { value += char; isEscaped = false; continue; } const char = command.charAt(i); switch (char) { case " ": if (!quote && i !== start) { result.push(command.substring(start, i)); start = i + 1; if (!quote && value) { result.push(value); value = ""; } break; case "'": Loading @@ -53,11 +53,14 @@ export function splitCommand(command: string): string[] { case "\\": isEscaped = true; break; default: value += char; break; } } if (start < command.length) { result.push(command.substring(start)); if (value) { result.push(value); } return result; Loading
libraries/android-bin/src/cmd/utils.ts +1 −9 Original line number Diff line number Diff line import { splitCommand } from "@yume-chan/adb"; import type { Cmd } from "./service.js"; export function resolveFallback( Loading Loading @@ -31,13 +29,7 @@ export function serializeAbbService( ): string { checkCommand(command); // `abb` mode doesn't use `sh -c` to execute to command, // so it doesn't accept escaped arguments. // `splitCommand` can be used to remove the escaping, // each item in `command` must be a single argument. const newCommand = command.map((arg) => splitCommand(arg)[0]!); // `abb` mode uses `\0` as the separator, allowing space in arguments. // The last `\0` is required for older versions of `adb`. return `${prefix}:${newCommand.join("\0")}\0`; return `${prefix}:${command.join("\0")}\0`; }