Repository navigation
fs-safe 0.20.0
Highlights
- Older Linux systems: when
openat2is absent (Linux before 5.6) or blocked by seccomp, native operations fall back to a guarded no-follow walk instead of failing withENOSYS. Nested no-clobber moves keep working, and GNU x64/arm64 bindings now target glibc 2.28, so native operations load on RHEL 8-family systems. (#686, #685; fixes #572, #511, #548) - Path hardening: trash moves stay inside allowed roots, symlink-parent checks inspect raw segments before dotdot normalization, relative-escape checks recognize either Windows separator and nested escapes, and safe path segments reject Windows reserved device names. Thanks @SebTardif. (#611, #615, #614, #612)
- ZIP admission per operation: portable ZIP reads and extraction bind entry selection to the admitted archive, name, and decoder object, and verify payloads against the admitted CRC and size. Substituted, renamed, or replaced decoder entries are rejected. (#660)
Features
- Retained symlink publication:
retainSymlinkInDirectory()on the advanced surface holds an explicitly identified POSIX symlink through exact-slot no-replace publication and explicit recovery, preserving observed foreign replacements and uncertain outcomes. (#682) - Batched Windows ACL facts:
readOwnerAndDaclBatch()inspects ordered paths in one isolated native worker or one PowerShell process, with a configurable whole-batch timeout and bounded output. Results are bounded during collection; oversized batches reject withtoo-largebefore later paths are queried. (#669, #680) - Atomic text options:
writeTextAtomic()forwards the existingbeforeRenamehook andtempPrefixoption to atomic replacement, keeping its validation and identity checks. (#580)
Fixes
- Lock exit cleanup: leave raw sidecars in place when Windows reports an unknown device or inode, while keeping token-owned cleanup working when the descriptor and path identities legitimately differ (for example on VirtioFS). Thanks @SebTardif. (#617)
- Retained symlink errors: preserve uncertain publication outcomes and cached cleanup/recovery failures when inspecting thrown error metadata fails, retaining the original cause without retrying mutations, callbacks, or descriptor closes. (#684)
- Create collision cleanup: atomic and streamed creates remove their private stage when the JavaScript fallback observes a competing destination before publication; failures after a link attempt retain their existing recovery evidence. (#683)
Compatibility
- Safe path segments now reject Windows reserved device names (
CON,NUL,COM1,CON.json, …) on every platform, because segments are portable identifiers. Temporary filename sanitization still suffixes them (CON.txtbecomesCON_.txt). (#612) assertNoSymlinkParents()and guarded appends withrejectSymlinkParentsreject raw spellings whose dotdot segments would cancel a symlink or re-enter the root after leaving it. (#615)- Without
openat2, beneath opens reportbest-effortcontainment instead ofkernel-atomic, anonymousO_TMPFILEopens reportENOTSUP, and bounded tree cleanup fails closed withhelper-unavailablebecause it requiresRESOLVE_NO_XDEV. (#686) - The Linux GNU binding floor is glibc 2.28 for both x64 and arm64 (arm64 was previously built against 2.17), matching Node 22's own Linux baseline. (#685)
Published packages
| Package | Registry tarball | Verified integrity | Provenance |
|---|---|---|---|
| @openclaw/fs-safe-linux-x64-gnu@0.20.0 | tgz | sha512-XCdGPfRG3739ILzhqUO2qACOVQ6V7Tnc88IJ1YPg13IleqsjWwegqQtnWhralw3bO82gnxRzu81Hw2cJmPSqsQ== |
verified attestation |
| @openclaw/fs-safe-linux-x64-musl@0.20.0 | tgz | sha512-t27hoQYnGpw7xBAgTIleUR2Owy8bqtVAUpR7tCQ8F0xnhrW0ZpkN8zHq9U+0luaK352+C0yLl/BQ1/Se/1iIFw== |
verified attestation |
| @openclaw/fs-safe-linux-arm64-gnu@0.20.0 | tgz | sha512-enO85SSP1wfQA+rnyKS7T2waXWmNRlveMyR5z4EF7APmXwV5TcFQlGQbdz2H8Z2MMvr3A2nlw6vEYV/wqpRZGA== |
verified attestation |
| @openclaw/fs-safe-linux-arm64-musl@0.20.0 | tgz | sha512-k3g84E/TdxowZlfMO3xwNcaP4UFrCdCSBy1TjP52ppbIPmtY78pVsyCkn+D7NrlrJCU0VdUDjuAuZGRO2N+98A== |
verified attestation |
| @openclaw/fs-safe-darwin-x64@0.20.0 | tgz | sha512-4p6pJ8/QYgAwBj4yzQNzcFn2x7Lw0gZ/9VVcCfBTO75kuad18vGVUKgZFlBIDvKjQ02KAk4MftAYtvlz+iamUw== |
verified attestation |
| @openclaw/fs-safe-darwin-arm64@0.20.0 | tgz | sha512-96lFpqGy6kSiLSxQGme9JTivbH1qolJLBYNGAESgdRS896RlpW22XTPZrBlXQ9yHd3Y0+BI5JXUq4JjKC9B0wQ== |
verified attestation |
| @openclaw/fs-safe-win32-x64-msvc@0.20.0 | tgz | sha512-DTEzowTyObbJd9dlC/CResyhMuIaH4rVx2lph8UFQC/ag1D7C3Ss6GFE7bg00jonjDEpoBFtgZlKyqmwosJ/gA== |
verified attestation |
| @openclaw/fs-safe@0.20.0 | tgz | sha512-XEFZEnQXiJt0CDfQgjvfWk1bYFrB4mZQv7pNXu9FwvuQ+PbW1lumHX/ICLUlISxDRc5vjMQZLRAbRVAl79wCeQ== |
verified attestation |
Release proof: GitHub Actions run.