mirror of
https://github.com/mvschwarz/openrig.git
synced 2026-11-07 05:56:21 -10:00
fix(cli): refuse nonregular experiment inputs without waiting (#670)
The experimental project input reader opens its file non-blocking, so a named pipe with no writer is refused immediately by the existing bounded-regular-file check instead of hanging the command. Regular files read as before.
This commit is contained in:
1 parent
d0ae339c23
commit
a60ab60d72
2 files changed
+28
-1
No files matched your search
@@ -14,7 +14,7 @@ export type JevResult = { status: "answered"; answers: Answers; model: string }
|
||||
const hash = (text: string) => "sha256:" + createHash("sha256").update(text).digest("hex");
|
||||
|
||||
export function readBounded(file: string, limit = 1024 * 1024): string {
|
||||
const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
||||
const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
|
||||
try {
|
||||
const s = fs.fstatSync(fd);
|
||||
if (!s.isFile() || s.size > limit) throw Error("input must be a bounded regular file");
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { afterEach, expect, it } from "vitest";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { spawn, execFileSync } from "node:child_process";
|
||||
import { readBounded } from "../src/commands/project-jev.js";
|
||||
|
||||
const dirs: string[] = [];
|
||||
afterEach(() => { for (const dir of dirs.splice(0)) fs.rmSync(dir, { recursive: true, force: true }); });
|
||||
function fixture() { const dir = fs.mkdtempSync(path.join(os.tmpdir(), "jev-input-native-")); dirs.push(dir); return dir; }
|
||||
it.skipIf(process.platform === "win32")("rejects an owned FIFO without waiting for its writer", async () => {
|
||||
const file = path.join(fixture(), "input.json"); execFileSync("mkfifo", [file]);
|
||||
const source = new URL("../src/commands/project-jev.ts", import.meta.url).href;
|
||||
const script = `import { readBounded } from ${JSON.stringify(source)}; try { readBounded(process.argv[1]); process.exitCode=2; } catch(e) { console.log(e.message); }`;
|
||||
const child = spawn(process.execPath, ["--import", "tsx", "--input-type=module", "-e", script, file], { stdio: ["ignore", "pipe", "pipe"] });
|
||||
let out = ""; child.stdout.on("data", (chunk) => { out += chunk; });
|
||||
let timedOut = false;
|
||||
const timer = setTimeout(() => { timedOut = true; child.kill("SIGKILL"); }, 10_000);
|
||||
const code = await new Promise<number | null>((resolve, reject) => { child.once("close", resolve); child.once("error", reject); });
|
||||
clearTimeout(timer);
|
||||
expect({ code, timedOut, out }).toEqual({ code: 0, timedOut: false, out: "input must be a bounded regular file\n" });
|
||||
});
|
||||
it("retains normal bounded-file reads and refuses an oversized regular file", () => {
|
||||
const file = path.join(fixture(), "input.json"); fs.writeFileSync(file, "source bytes");
|
||||
expect(readBounded(file, 12)).toBe("source bytes");
|
||||
expect(() => readBounded(file, 11)).toThrow("bounded regular file");
|
||||
});
|
||||
Reference in new issue
Block a user