From b47b2ff7eba5c6b690178f56a131729f8aa15d7c Mon Sep 17 00:00:00 2001 From: luvs01 Date: Fri, 7 Aug 2026 16:54:55 +0900 Subject: [PATCH] fix(codex): reject profile FIFOs without blocking --- src/codex/native-profile-store.ts | 2 +- tests/native-profile-store.test.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/codex/native-profile-store.ts b/src/codex/native-profile-store.ts index 7afba81730..794e8ea006 100644 --- a/src/codex/native-profile-store.ts +++ b/src/codex/native-profile-store.ts @@ -383,7 +383,7 @@ function readBounded(path: string, limit: number, testSeam?: BoundedReadTestSeam testSeam?.beforeOpen?.(path); const flags = process.platform === "win32" ? fsConstants.O_RDONLY - : fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW; + : fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW | fsConstants.O_NONBLOCK; fd = openSync(path, flags); const opened = fstatSync(fd, { bigint: true }); if (!opened.isFile() || opened.size > BigInt(limit)) throw new Error("invalid bounded file"); diff --git a/tests/native-profile-store.test.ts b/tests/native-profile-store.test.ts index e8cc9d8d80..c392b3ffb0 100644 --- a/tests/native-profile-store.test.ts +++ b/tests/native-profile-store.test.ts @@ -1,4 +1,5 @@ import { afterEach, describe, expect, test } from "bun:test"; +import { execFileSync } from "node:child_process"; import { appendFileSync, mkdirSync, mkdtempSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; @@ -382,6 +383,13 @@ describe("native-profile recovery journal storage", () => { expect((caught as NativeProfileError).code).toBe("VAULT_INVALID"); }); + test.skipIf(process.platform === "win32")("rejects a vault FIFO without waiting for a writer", () => { + const store = context(); + execFileSync("mkfifo", [store.vaultPath]); + + expect(() => readNativeProfileVault(store)).toThrow(NativeProfileError); + }); + test("reads at most journal cap plus one when the opened journal grows after fstat", () => { const store = context(); const initial = serializeNativeProfileJournal(journal());