Skip to content

fix(programs): identify the input file by identity on Windows - #4861

Open
Huang-404-Q wants to merge 1 commit into
meta:devfrom
Huang-404-Q:fix/win-same-file-identity
Open

Huang-404-Q wants to merge 1 commit into
meta:devfrom
Huang-404-Q:fix/win-same-file-identity

Conversation

@Huang-404-Q

Copy link
Copy Markdown

What

On Windows, UTIL_isSameFile / UTIL_isSameFileStat fall back to strcmp, so any alternate spelling of the same path (case variant, ./ prefix, absolute vs relative, 8.3 name, hard link) is considered a different file. FIO_openDstFile() then opens that path with O_TRUNC, destroying the already-open source before it is read.

Repro with a 30000-byte a.bin on Windows:

zstd -f a.bin -o A.bin     # exit 0, a.bin becomes the 13-byte compressed empty frame

The exact-spelling control -o a.bin correctly refuses.

Fix

Under _WIN32, compare the volume serial number and file index from GetFileInformationByHandle instead of the path strings. UTIL_isSameFileStat uses the same helper. Non-Windows paths are unchanged.

Verification

Built programs/zstd with MinGW gcc 13.2 and ran the cases:

output path before after
a.bin refuses, input intact refuses, input intact
A.bin (case variant) exit 0, input truncated to 13 bytes refuses, input intact
./a.bin exit 0, input truncated refuses, input intact
out.zst succeeds succeeds (283 bytes)

Also added tests/cli-tests/file-stat/compress-file-to-itself.sh, which uses ./file (the same path on every platform) and checks the input is unchanged. The local CLI test runner could not run on this Windows host because it creates symlinks (WinError 1314); the exact commands were verified manually as above.

UTIL_isSameFile and UTIL_isSameFileStat fall back to strcmp on Windows,
so alternate spellings of the same path (case variants, ./ prefixes,
absolute paths, hard links) are treated as different files.
FIO_openDstFile then opens the output with O_TRUNC and destroys the input
before it is read.

Compare the volume serial number and file index from
GetFileInformationByHandle instead, which identifies the file regardless
of how the path is spelled. Adds a CLI test that compresses a file onto
itself via ./file and checks the input is left intact.
@meta-cla meta-cla Bot added the CLA Signed label Oct 23, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant