diff --git a/packages/opencode/test/tool/write.test.ts b/packages/opencode/test/tool/write.test.ts index 97939c10519e..8e42b15e72ca 100644 --- a/packages/opencode/test/tool/write.test.ts +++ b/packages/opencode/test/tool/write.test.ts @@ -152,29 +152,45 @@ describe("tool.write", () => { }) describe("file permissions", () => { - test("sets file permissions when writing sensitive data", async () => { - await using tmp = await tmpdir() - const filepath = path.join(tmp.path, "sensitive.json") + const base = 0o666 + async function put(dir: string, filepath: string, content: string) { await Instance.provide({ - directory: tmp.path, + directory: dir, fn: async () => { const write = await WriteTool.init() await write.execute( { filePath: filepath, - content: JSON.stringify({ secret: "data" }), + content, }, ctx, ) - - // On Unix systems, check permissions - if (process.platform !== "win32") { - const stats = await fs.stat(filepath) - expect(stats.mode & 0o777).toBe(0o644) - } }, }) + } + + async function writeAndCheckMode(umask: number, expected: number) { + if (process.platform === "win32") return + await using tmp = await tmpdir() + const filepath = path.join(tmp.path, "sensitive.json") + const prev = process.umask(umask) + try { + await put(tmp.path, filepath, JSON.stringify({ secret: "data" })) + + const stats = await fs.stat(filepath) + expect(stats.mode & 0o777).toBe(expected) + } finally { + process.umask(prev) + } + } + + test("base mode is 0o666 before umask masking", () => writeAndCheckMode(0o000, base)) + test("respects umask 0o022 → 0o644", () => writeAndCheckMode(0o022, base & ~0o022)) + test("respects corner umask 0o027 → 0o640", () => writeAndCheckMode(0o027, base & ~0o027)) + test("respects umask 0o077 → 0o600", () => writeAndCheckMode(0o077, base & ~0o077)) + test("0o777 fully masks the 0o666 base mode", () => { + expect(base & ~0o777).toBe(0o000) }) })