The posix write helper rejected any path whose computed
path.relative(root, resolved) string-began with "..", even when the
resolved path was fully inside the root. That matched literal
filenames whose first segment merely starts with the two characters
".." (e.g. "..%2fpwned.txt", "..%00/pwned.txt") and produced an
"outside-workspace" error for paths that do not actually escape
the root. The real boundary is already enforced upstream by
resolvePathInRoot's path.resolve + isPathInside check, so the
extra startsWith("..") guard added no security value while
introducing platform divergence (windows did not have it). Drop the
guard, keep the path.isAbsolute check.
Recategorize the three former SAFE_REJECTED_SUSPICIOUS_WRITE_PAYLOADS
test inputs so the test reflects what each platform actually does:
- "..%2fpwned.txt" and "..%00/pwned.txt" are literal names that
resolve fully inside root on both platforms; move them to
LITERAL_SUSPICIOUS_WRITE_PAYLOADS (accepted everywhere).
- "..\pwned.txt" is a real traversal on windows where "\\" is a
separator, but a literal filename on posix where "\\" is a regular
name character; move it to POSIX_LITERAL_SUSPICIOUS_WRITE_PAYLOADS
(accepted on posix, rejected on windows).
The literal-directory check in the same test uses fsp.stat on
windows since safeRoot.list goes through the pinned helper that is
unavailable on win32, matching the pattern already used a few lines
up. Bump the per-test timeout to 15s for slow windows fs under
parallel test load.
Drop a stale explanatory comment in expandHomePrefix.
After: 254 passed, 0 failed, 66 skipped on windows.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Run the check job on windows-latest in addition to ubuntu so the
windows code paths (no O_NOFOLLOW, node fallbacks for fd-relative
ops, ACL inspection) are exercised on every PR rather than only
documented.
Make the test suite pass on the new windows runner by addressing
the platform-specific failures:
- Long happy-path tests that mix supported (mkdir, write, read) and
unsupported (stat, list, move, exists) operations are guarded
with skipIf(process.platform === "win32") since the pinned
filesystem helper throws "unsupported-platform" on win32 by
design (src/pinned-python.ts).
- Short focused tests where the unsupported operation is the whole
point (pinned-python, pinned-write-fallback-coverage,
write-boundary-bypass symlink-move) split into runIf(non-win32)
and runIf(win32) tests, with the windows variant asserting
unsupported-platform.
- The expectFsSafeCode helper accepts unsupported-platform on
windows; new expectedFsSafeCode helper substitutes for
per-rejects.toMatchObject sites where the windows code differs
from posix (e.g. path-alias / not-found returning
unsupported-platform via the helper layer).
- secure-file-reads test split into a posix happy-path runIf and a
windows runIf that asserts permission-unverified, since ACL
inspection has no portable equivalent on windows
(src/secure-file.ts:177).
- safeFileURLToPath test uses hardcoded platform-specific input/
output instead of building the URL via pathToFileURL+fileURLToPath
so the assertion verifies the function directly.
- Fix expandHomePrefix to normalize path separators by splitting via
path.normalize + path.sep and rejoining via path.join. Apply the
same segment-based check to resolveHomeRelativePath and
resolveOsHomeRelativePath. Drop input.trim() — whitespace is a
valid filename character on both platforms and env-var inputs are
already trimmed upstream via normalizeOptionalString.
- coverage-more's "normalizes empty temp names" decomposes the
result with path.dirname/path.basename instead of regex-matching
a path-separator literal.
- extracted-helpers' path-helpers test builds its root with
path.resolve so the drive letter is present on windows.
- additional-boundary-bypass guards its "..\evil.txt" sanitizer
assertion behind a non-win32 check (windows reserves "\" as a
path separator and cannot have it in a filename).
- coverage-more's sibling temp test guards just the posix file-mode
assertion (stat.mode & 0o777 === 0o600), which has no analog on
windows. The syncing behaviour the test actually targets still
runs on both platforms.
- Raise test/new-primitives.test.ts size budget to 1500 to
accommodate the secure-file-reads test split.
After: 253 passed, 1 failed, 66 skipped on windows-11-arm64. The
single remaining failure is a separate library-side gap (a
SAFE_REJECTED_SUSPICIOUS_WRITE_PAYLOADS payload resolves on windows
instead of rejecting) and will be tracked in a follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1200×630 PNG (rendered from SVG) wired into og:image / twitter:image meta
on every page. Dark theme matches the site, shield mark + wordmark + tagline
+ url. Twitter card upgraded to summary_large_image.