diff --git a/flake.nix b/flake.nix index 80677c9..3dce74b 100644 --- a/flake.nix +++ b/flake.nix @@ -65,6 +65,7 @@ esbuild dist/src/bindings/portable-client-cli.js --bundle --platform=node --target=node24 --format=esm --outfile=quixos-codegen-client.mjs esbuild dist/src/bindings/react-platform.js --bundle --platform=node --target=node24 --format=esm --outfile=react-platform.mjs esbuild dist/src/capability-language/tool-cli.js --bundle --platform=node --target=node24 --format=esm --outfile=quixos-qx.mjs + esbuild dist/src/capability-language/source-check-driver.js --bundle --platform=node --target=node24 --format=esm --outfile=source-check-driver.mjs runHook postBuild ''; doCheck = true; @@ -132,6 +133,7 @@ install -m644 client-codegen.mjs "$out/libexec/quixos-protocol/client-codegen.mjs" install -m644 react-platform.mjs "$out/libexec/quixos-protocol/react-platform.mjs" install -m644 quixos-codegen-ts.mjs quixos-qx.mjs "$out/libexec/quixos-protocol/" + install -m644 source-check-driver.mjs "$out/libexec/quixos-protocol/" install -m644 quixos-codegen-client.mjs "$out/libexec/quixos-protocol/" install -m644 quixos-descriptor-check.mjs "$out/libexec/quixos-protocol/quixos-descriptor-check.mjs" install -m644 quixos-capability-compile.mjs "$out/libexec/quixos-protocol/quixos-capability-compile.mjs" diff --git a/src/capability-language/checked-build.ts b/src/capability-language/checked-build.ts index 7e2e7fd..5fe2122 100644 --- a/src/capability-language/checked-build.ts +++ b/src/capability-language/checked-build.ts @@ -128,6 +128,7 @@ export async function buildImmutableCandidate( log.once("open", () => resolve()); log.once("error", reject); }); + let logBytes = 0; const run = async (executable: string, args: string[]) => await new Promise((resolve, reject) => { let output = "", @@ -140,9 +141,18 @@ export async function buildImmutableCandidate( }; log.on("error", failedLog); child.stdout.on("data", (chunk) => { - output += chunk; + if (failure) return; + if (Buffer.byteLength(output) + chunk.length > 65536) + failedLog(new Error("Candidate checker output exceeds 64 KiB")); + else output += chunk; }); child.stderr.on("data", (chunk) => { + if (failure) return; + logBytes += chunk.length; + if (logBytes > 16 * 1024 * 1024) { + failedLog(new Error("Candidate checker log exceeds 16 MiB")); + return; + } log.write(chunk); tail = (tail + String(chunk)).slice(-6000); }); diff --git a/src/capability-language/source-check-driver.ts b/src/capability-language/source-check-driver.ts new file mode 100644 index 0000000..36f6350 --- /dev/null +++ b/src/capability-language/source-check-driver.ts @@ -0,0 +1,8 @@ +import { buildImmutableCandidate } from "./checked-build.js"; + +// Installed platform driver, run only inside the sealed checker's unprivileged +// evaluator. Authored flakes never become the outer evaluator program. +const [repository, commit, log] = process.argv.slice(2); +if (!repository || !commit || !log || process.argv.length !== 5) + throw Error("source-check-driver REPOSITORY COMMIT LOG"); +process.stdout.write((await buildImmutableCandidate({ repository, commit }, "workspace", log)) + "\n");