From cc2469f1fe99b2cc808c59b9f51d2f7ed46425f8 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 28 Aug 2026 17:37:15 +0000 Subject: [PATCH] fix(test): gate the symlink-refusal test to POSIX and drop the umask assumption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The symlink regression test exercised the POSIX O_NOFOLLOW branch but ran on Windows, where restrictDirectoryPermissions takes the icacls branch and stat has no POSIX modes (0o666 always) — windows-free-tests failed on mode 493 vs 438. Early-return on win32 like every sibling test in the file, and assert the target's mode is UNCHANGED (captured post-mkdir) instead of hardcoding 0o755, which a strict umask would also break. Co-Authored-By: Claude Fable 5 --- browse/test/file-permissions.test.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/browse/test/file-permissions.test.ts b/browse/test/file-permissions.test.ts index 6461cf075..f3e1ea727 100644 --- a/browse/test/file-permissions.test.ts +++ b/browse/test/file-permissions.test.ts @@ -255,17 +255,23 @@ describe('repairBrokenDacl', () => { }); // Symlinked state dir (dotfiles-managed ~/.gstack via stow/chezmoi): the // fd-anchored path refuses to follow it (O_NOFOLLOW) — the refusal must warn, -// never throw, and never chmod the symlink target. +// never throw, and never chmod the symlink target. POSIX-branch behavior: +// Windows takes the icacls branch and has no POSIX modes (stat reports 0o666), +// so gate like the sibling tests above. test('restrictDirectoryPermissions warns and skips a symlinked dir without throwing', () => { + if (process.platform === 'win32') return; const base = fs.mkdtempSync(path.join(os.tmpdir(), 'fp-symlink-')); const target = path.join(base, 'real'); const link = path.join(base, 'link'); fs.mkdirSync(target, { mode: 0o755 }); fs.symlinkSync(target, link); + // Capture the actual post-umask mode rather than assuming 0o755 — a strict + // umask (077) would legitimately yield 0o700 at creation time. + const modeBefore = fs.statSync(target).mode & 0o777; try { expect(() => restrictDirectoryPermissions(link)).not.toThrow(); // Target permissions untouched — the link was never followed. - expect(fs.statSync(target).mode & 0o777).toBe(0o755); + expect(fs.statSync(target).mode & 0o777).toBe(modeBefore); } finally { fs.rmSync(base, { recursive: true, force: true }); }