fix(windows): skip unreliable dev comparison in fs-safe openVerifiedLocalFile#25708
Closed
kevinWangSheng wants to merge 1 commit intoopenclaw:mainfrom
Closed
fix(windows): skip unreliable dev comparison in fs-safe openVerifiedLocalFile#25708kevinWangSheng wants to merge 1 commit intoopenclaw:mainfrom
kevinWangSheng wants to merge 1 commit intoopenclaw:mainfrom
Conversation
…ocalFile On Windows, device IDs (dev) returned by handle.stat() and fs.lstat() may differ even for the same file, causing false-positive 'path-mismatch' errors when reading local media files. This fix introduces a statsMatch() helper that: - Always compares inode (ino) values - Skips device ID (dev) comparison on Windows where it's unreliable - Maintains full comparison on Unix platforms Fixes openclaw#25699
Comment on lines
+49
to
+58
| function statsMatch(stat1: Stats, stat2: Stats): boolean { | ||
| if (stat1.ino !== stat2.ino) { | ||
| return false; | ||
| } | ||
| // On Windows, dev values are unreliable across different stat sources | ||
| if (process.platform !== "win32" && stat1.dev !== stat2.dev) { | ||
| return false; | ||
| } | ||
| return true; | ||
| } |
Contributor
There was a problem hiding this comment.
The existing src/infra/safe-open-sync.ts:sameFileIdentity() uses a more nuanced approach: it checks if either dev value is 0 on Windows before falling back to ino-only comparison. Your implementation unconditionally skips dev comparison on all Windows systems. Consider aligning with the existing pattern:
Suggested change
| function statsMatch(stat1: Stats, stat2: Stats): boolean { | |
| if (stat1.ino !== stat2.ino) { | |
| return false; | |
| } | |
| // On Windows, dev values are unreliable across different stat sources | |
| if (process.platform !== "win32" && stat1.dev !== stat2.dev) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| function statsMatch(stat1: Stats, stat2: Stats): boolean { | |
| if (stat1.ino !== stat2.ino) { | |
| return false; | |
| } | |
| // On Windows, dev values are unreliable across different stat sources | |
| const devMatch = | |
| stat1.dev === stat2.dev || | |
| (process.platform === "win32" && (stat1.dev === 0 || stat2.dev === 0)); | |
| if (!devMatch) { | |
| return false; | |
| } | |
| return true; | |
| } |
This provides better security on Windows systems where both dev values are valid and non-zero.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/infra/fs-safe.ts
Line: 49-58
Comment:
The existing `src/infra/safe-open-sync.ts:sameFileIdentity()` uses a more nuanced approach: it checks if *either* `dev` value is 0 on Windows before falling back to ino-only comparison. Your implementation unconditionally skips `dev` comparison on all Windows systems. Consider aligning with the existing pattern:
```suggestion
function statsMatch(stat1: Stats, stat2: Stats): boolean {
if (stat1.ino !== stat2.ino) {
return false;
}
// On Windows, dev values are unreliable across different stat sources
const devMatch =
stat1.dev === stat2.dev ||
(process.platform === "win32" && (stat1.dev === 0 || stat2.dev === 0));
if (!devMatch) {
return false;
}
return true;
}
```
This provides better security on Windows systems where both `dev` values are valid and non-zero.
How can I resolve this? If you propose a fix, please make it concise.
Contributor
|
Superseded by #25917, now merged to What landed from this line of work:
Thank you for surfacing and narrowing the root cause quickly; this directly informed the final landed fix. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Windows, inbound images fail with
Local media path is not safe to read/path changed during read. The root cause is a false-positive inopenVerifiedLocalFilewherehandle.stat()andfs.lstat()return differentdevvalues on Windows, causing thepath-mismatchcheck to throw even though the file is stable and not a symlink.Root Cause
In
src/infra/fs-safe.ts:On Windows,
handle.stat().devdiffers fromfs.lstat().deveven for the same file. This triggers the error even though the file is stable and not a symlink.Fix
Introduce a
statsMatch()helper that:ino) valuesdev) comparison on Windows where it's unreliableTesting
pnpm buildpassespnpm lintpassesFixes #25699
Greptile Summary
Fixes Windows media path verification by introducing a
statsMatch()helper that skips unreliable device ID (dev) comparison on Windows while maintaining inode (ino) verification. The fix resolves false-positive "path changed during read" errors whenhandle.stat()andfs.lstat()return different device IDs for the same file on Windows.statsMatch()helper function with platform-specific stat comparison logicdev+inoverification on Unix platformsdevcomparison on Windows where it's known to be unreliableThe approach is reasonable for Windows compatibility, though consider aligning with the existing
sameFileIdentity()pattern insrc/infra/safe-open-sync.tswhich uses a more targeted fallback (checking if eitherdevis 0 rather than unconditionally skippingdevcomparison).Confidence Score: 4/5
sameFileIdentity()pattern insafe-open-sync.ts, but the current approach is valid and well-documented.Last reviewed commit: f59ed21
Context used:
dashboard- CLAUDE.md (source)