Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit f4ab3e00 authored by Simon Chan's avatar Simon Chan
Browse files

feat(adb): let subprocess API escape each argument

parent a5d0417e
Loading
Loading
Loading
Loading
+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", () => {
@@ -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",
        ]);
    });
});
+11 −8
Original line number Diff line number Diff line
@@ -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 "'":
@@ -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;
+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(
@@ -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`;
}