You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Windows equality check does not guarantee uniqueness on ReFS #63
This issue is a bit pedantic (mostly because nobody actually uses ReFS), but while discussing file equality checks with a friend I remarked on how this crate conducts the check on Windows by calling GetInformationByHandle and checking some of its output members.
I remarked that the checks done by this crate should be sufficient considering the docs say:
You can compare the VolumeSerialNumber and FileIndex members returned in the BY_HANDLE_FILE_INFORMATION structure to determine if two paths map to the same target; for example, you can compare two file paths and determine if they map to the same directory.
However, he noted that the BY_HANDLE_FILE_INFORMATION docs state:
The ReFS file system, introduced with Windows Server 2012, includes 128-bit file identifiers. To retrieve the 128-bit file identifier use the GetFileInformationByHandleEx function with FileIdInfo to retrieve the FILE_ID_INFO structure. The 64-bit identifier in this structure is not guaranteed to be unique on ReFS.
i.e. for those trailblazers out there who might be using ReFS, the underlying winapi-util crate should probably be using data returned by GetFileInformationByHandleEx and using a 128-bit identifier instead. Since the context really only matters for this crate though, I'm filing this as an issue here.
Some additional context, I used to work on the Hyper-V security team and my friend worked on the Windows Sandbox security team. I never really had to deal with untrusted file paths considering Hyper-V threat model, but he mentioned that apparently we would call GetFinalPathNameByHandle() with the FILE_NAME_NORMALIZED flag when doing security-sensitive file operations and comparing the output path. I'm not trying to suggest that the checks done by this crate shouldn't be sufficient (especially since the docs explicitly say otherwise), but now I can't help but wonder if there's a reason why we weren't checking similar info.
// It seems straight-forward enough to modify this code to use
// `FILE_ID_INFO` when available (minimum Windows Server 2012), but I don't
// have access to such Windows machines.
I can't remember why I didn't follow through with that. Maybe something about it not being supported on older versions of Windows? It looks like it should probably be fine to use for now.
Some additional context, I used to work on the Hyper-V security team and my friend worked on the Windows Sandbox security team. I never really had to deal with untrusted file paths considering Hyper-V threat model, but he mentioned that apparently we would call GetFinalPathNameByHandle() with the FILE_NAME_NORMALIZED flag when doing security-sensitive file operations and comparing the output path. I'm not trying to suggest that the checks done by this crate shouldn't be sufficient (especially since the docs explicitly say otherwise), but now I can't help but wonder if there's a reason why we weren't checking similar info.
I've seen folks do a similar thing on Unix as well.
I think that technique works, but it may be more costly. In contrast, the technique used in this crate doesn't require comparing file paths or doing potentially costly canonicalization on the path itself. Indeed, this crate doesn't even require a path at all. You can just pass in a File. Or even use stdin/stdout/stderr. Indeed, this latter thing is a critical piece that ripgrep uses to determine if a file it wants to search is equivalent to the process's stdout (because if it is, searching and printing to it can result in an infinite positive feedback loop). If ripgrep had to canonicalize every path just to do this check, the resulting performance would be disastrous.
Activity
BurntSushi commentedon Oct 17, 2025
Yes, this is called out explicitly in the code:
same-file/src/win.rs
Lines 17 to 25 in e7d851b
I can't remember why I didn't follow through with that. Maybe something about it not being supported on older versions of Windows? It looks like it should probably be fine to use for now.
I've seen folks do a similar thing on Unix as well.
I think that technique works, but it may be more costly. In contrast, the technique used in this crate doesn't require comparing file paths or doing potentially costly canonicalization on the path itself. Indeed, this crate doesn't even require a path at all. You can just pass in a
File. Or even use stdin/stdout/stderr. Indeed, this latter thing is a critical piece that ripgrep uses to determine if a file it wants to search is equivalent to the process's stdout (because if it is, searching and printing to it can result in an infinite positive feedback loop). If ripgrep had to canonicalize every path just to do this check, the resulting performance would be disastrous.