mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
Closes #11360. ## Summary - Cap combined stdout/stderr with `ExecOptions.maxBuffer`, defaulting to the smaller of 256 MiB and the runtime string limit. Invalid explicit limits reject before spawning. - Terminate oversized commands and return `truncated: true`, `killed: true`, and a nonzero exit code. Close output pipes so writing descendants cannot keep the call pending, and discard incomplete UTF-8 suffixes rather than adding replacement characters. - Fix SIGKILL escalation for children that ignore SIGTERM, and simplify completion to `await` with one cleanup block and result. - Document the API and add regressions for byte limits, shell descendants, UTF-8 chunk boundaries, and 32-bit runtime limits. `ExecResult.truncated` is required. Existing extensions reading execution results continue working; typed mocks or wrappers constructing results must add the field. ## Verification - `npm run build` and the post-rebase `npm run build:offline` - `npm run check` - 39 focused execution and extension tests - `./test.sh` passes after building the env daemon. Earlier runs hit remote-cleanup and reftable-watcher timeouts; both passed in focused reruns and the final full run.
25 lines
1,021 B
TypeScript
25 lines
1,021 B
TypeScript
import * as buffer from "node:buffer";
|
|
import { expect, it, vi } from "vitest";
|
|
import { execCommand } from "../src/core/exec.ts";
|
|
|
|
vi.mock("node:buffer", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof buffer>();
|
|
return {
|
|
...actual,
|
|
// 32-bit Node's maximum is 16 bytes below 256 MiB.
|
|
constants: { ...actual.constants, MAX_STRING_LENGTH: 268_435_440 },
|
|
};
|
|
});
|
|
|
|
// Regression tests for https://github.com/earendil-works/pi/issues/11360
|
|
it("executes with the default cap when the runtime string limit is below 256 MiB", async () => {
|
|
const result = await execCommand(process.execPath, ["-e", 'process.stdout.write("ok")'], process.cwd());
|
|
|
|
expect(result).toEqual({ stdout: "ok", stderr: "", code: 0, killed: false, truncated: false });
|
|
});
|
|
|
|
it("still rejects an explicit cap above the runtime string limit", async () => {
|
|
await expect(
|
|
execCommand(process.execPath, ["-e", ""], process.cwd(), { maxBuffer: buffer.constants.MAX_STRING_LENGTH + 1 }),
|
|
).rejects.toThrow(RangeError);
|
|
});
|