Uh oh!
There was an error while loading. Please reload this page.
programs: strip trailing '\r' from --filelist entries on Windows - #4766
Open
jaypatrickhoward wants to merge 1 commit into
Open
programs: strip trailing '\r' from --filelist entries on Windows#4766jaypatrickhoward wants to merge 1 commit into
jaypatrickhoward wants to merge 1 commit into
Conversation
jaypatrickhoward
marked this pull request as draft
September 7, 2026 05:06
jaypatrickhowardforce-pushed
the
filelist-crlf
branch
from
September 7, 2026 05:31
592e461 to
060ea1eComparejaypatrickhowardforce-pushed
the
filelist-crlf
branch
7 times, most recently
from
September 7, 2026 13:29
33b35d5 to
078603bCompare`--filelist` stopped accepting Windows CRLF line endings in 165e52c ("first implementation supporting Process Substitution", facebook#4349). That rewrite reads the list into a buffer opened in binary mode and splits it on '\n' alone. Previously the list was opened in text mode, where the Windows CRT translated CRLF to LF before the parser saw it, so stripping '\n' was sufficient. In binary mode the CR survives into every path: zstd: can't stat a.txt : No such file or directory -- ignored The '\r' is invisible in that message, which makes it awkward to diagnose. Strip a trailing '\r' when the line pointers are built, but only on Windows, where CRLF is the native line separator and a '\r' cannot be used in a filename. Elsewhere '\r' is a legal filename byte and is left alone, so behaviour on those platforms is unchanged. This restores the pre-regression behaviour exactly, on every platform, without adding a new one. Adds a playTests case, guarded to Windows, that fails without the fix.
jaypatrickhowardforce-pushed
the
filelist-crlf
branch
from
September 7, 2026 13:34
078603b to
e74a51aComparejaypatrickhoward
marked this pull request as ready for review
September 7, 2026 13:57
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 freeto 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.
On Windows,
--filelistno longer accepts file lists that use CRLF line endings. Every path retains a trailing\r, so each entry fails to resolve:The
\ris invisible in that message, which makes the failure awkward to diagnose.Cause
The list used to be opened in text mode (
fopen(..., "r")), where the Windows CRT translates CRLF to LF before the parser sees it, so stripping the trailing'\n'inreadLineFromFile()was sufficient. There was never an explicit'\r'strip — the behaviour depended entirely on that translation.#4349 (
165e52ce, "first implementation supporting Process Substitution") reads the whole list into a buffer opened in binary mode and splits it on'\n'alone. Binary mode performs no translation, so the CR now survives into every filename. Because the previous behaviour was implicit, nothing flagged its loss.Binary mode is the right choice for the new implementation, so the fix is to strip the CR explicitly.
Fix
Drop a trailing
'\r'inUTIL_createLinePointers(), where each line's extent is already known — but only on Windows.The guard matters, because the two interesting inputs are byte-identical. A CRLF-terminated line naming
a.txt, and an LF-terminated line naming a file actually calleda.txt\r, are botha.txt \r \n. No parser can distinguish them, so stripping unconditionally would trade one behaviour for the other. Guarding on_WIN32picks the interpretation that is correct on each platform:'\r'was never usable by zstd in the first place — see the note below the table. So stripping loses nothing.'\r'is a legal byte in a filename, so it is left untouched.This reproduces the pre-regression behaviour exactly, on both platforms, without introducing a new one.
Measured behaviour
One probe script, run on both platforms;
zstd.exebuilt with MSVC (x64, Release).dev'\r', Windows'\r', POSIXEvery cell matches the pre-#4349 column.
The third row deserves a note, since it is the one case this patch gives up. Such a filename can exist on NTFS — the probe's emulation layer did create one — but no
zstdbuild can open it, including before #4349: Win32 reserves the characters0x01-0x1Fin path names, so a native build never had access to it. Stripping the CR on Windows therefore removes no functionality that was previously available; it only stops a CRLF list from being misread.A CRLF list authored on Windows still fails when consumed on a POSIX host, as it always has. Making that work would be a new feature rather than a regression fix, and it cannot be done without giving up filenames ending in
'\r', so it is left alone here.Scope
Not yet released.
165e52ceis not an ancestor ofv1.5.7,v1.5.6orv1.5.5, and no tag contains it; it is an ancestor ofdevonly. This is adevregression that would first appear in the next release.Testing
A
playTests.shcase is added for the CRLF list, annotated with#4349so a future reader knows why it exists. It runs only where the strip is compiled in —MINGW*/MSYS*, matching the splittests/Makefilealready makes (it groupsCYGWIN_NT%with Linux and Darwin, and setsHOST_OS=MSYSforMINGW%/MSYS%).playTests.shaborts at exactly that test, reportingcan't statfor both entries.visual-runtime-testson both x64 and Win32 — the log shows the case executing and2 files compressed.playTests.shpasses on Windows and on POSIX.dev: 300 randomised list shapes, 147 of which contain CR, compared on exit status, files produced and stderr, with no differences. Expected, since the strip is compiled out there.165e52ce~1,dev, and this patch, then running one probe script on both platforms.