@openclaw/fs-safe 0.5.4 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.5 - 2026-08-12
4
+
5
+ ### Security and Correctness
6
+
7
+ - Prevent nondeterministic Windows read failures with `path-mismatch` when path-based stat reports zero file identity through libuv's FindFirstFile fallback under antivirus or indexer contention; zero Windows inodes are now treated as unknown identity like zero device serials.
8
+
3
9
  ## 0.5.4 - 2026-08-10
4
10
 
5
11
  **Highlight:** two security fixes in the publication path. If you run fs-safe on
@@ -1 +1 @@
1
- {"version":3,"file":"file-identity.d.ts","sourceRoot":"","sources":["../src/file-identity.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB,CAAC;AAUF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM,CAGlF;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,gBAAgB,EACvB,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,OAAO,CAWT"}
1
+ {"version":3,"file":"file-identity.d.ts","sourceRoot":"","sources":["../src/file-identity.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB,CAAC;AAsBF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM,CAGlF;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,gBAAgB,EACvB,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,OAAO,CAQT"}
@@ -5,18 +5,20 @@ function isZero(value) {
5
5
  function sameStatValue(left, right) {
6
6
  return typeof left === typeof right ? left === right : BigInt(left) === BigInt(right);
7
7
  }
8
+ function isStatValueProvablyDifferent(left, right, platform) {
9
+ if (sameStatValue(left, right)) {
10
+ return false;
11
+ }
12
+ return platform !== "win32" || (!isZero(left) && !isZero(right));
13
+ }
8
14
  export function sha256Hex(data, encoding) {
9
15
  const buffer = typeof data === "string" ? Buffer.from(data, encoding ?? "utf8") : data;
10
16
  return createHash("sha256").update(buffer).digest("hex");
11
17
  }
12
18
  export function sameFileIdentity(left, right, platform = process.platform) {
13
- if (!sameStatValue(left.ino, right.ino)) {
14
- return false;
15
- }
16
- // On Windows, path-based stat calls can report dev=0 while fd-based stat
17
- // reports a real volume serial; treat either-side dev=0 as "unknown device".
18
- if (sameStatValue(left.dev, right.dev)) {
19
- return true;
20
- }
21
- return platform === "win32" && (isZero(left.dev) || isZero(right.dev));
19
+ // When Windows cannot open a path for stat, libuv's FindFirstFile fallback reports dev=0 and
20
+ // ino=0. Treating either unknown value as a mismatch caused nondeterministic path-mismatch
21
+ // failures on legitimate reads under antivirus or indexer contention.
22
+ return (!isStatValueProvablyDifferent(left.dev, right.dev, platform) &&
23
+ !isStatValueProvablyDifferent(left.ino, right.ino, platform));
22
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/fs-safe",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Capability-style filesystem roots for Node.js apps that handle untrusted relative paths.",
5
5
  "keywords": [
6
6
  "filesystem",