Skip to content

mingw: use the full buffer when reading reparse points - #6507

Open
VirgilMing wants to merge 1 commit into
git-for-windows:mainfrom
VirgilMing:codex/mingw-long-symlink-targets
Open

VirgilMing wants to merge 1 commit into
git-for-windows:mainfrom
VirgilMing:codex/mingw-long-symlink-targets

Conversation

@VirgilMing

@VirgilMing VirgilMing commented Oct 22, 2026 •

Copy link
Copy Markdown

This PR fixes #6498.

Before this PR, read_reparse_point() passes MAX_PATH to the UTF-16-to-UTF-8 conversion, while both callers already allocate MAX_LONG_PATH bytes.
The conversion includes the terminating NUL, so the existing code fails with ERANGE (Result too large) for targets of 260 or more UTF-8 bytes.
The failure affects both readlink() and mingw_lstat() independently of core.longpaths; multibyte targets can reach that byte limit with far fewer than 260 characters.

  • This PR changes the conversion's capacity argument to MAX_LONG_PATH, matching the buffers that the callers already allocate.
  • This PR also adds one setup test and six regression cases to the existing t2031-checkout-long-paths.sh script.
    • The new cases cover ASCII and multibyte targets at 259, 260 and 261 UTF-8 bytes.
    • Each new case checks the decoded target and requires both the diff output and stderr to be empty.
    • The new tests disable the filesystem cache to exercise mingw_lstat() and set core.longpaths=false to demonstrate that the short link pathname does not require that option.
  • The existing buffer allocations and readlink() truncation behavior remain unchanged.

I built the unmodified main code (5cf10d74486d1e59b9ae6cedaedb4e26314e1557) and the patched code on native Windows 11 with MSYS2 UCRT64 GCC 16.2.0.
I used DEVELOPER=1, CFLAGS='-O0 -g' and NO_RUST=1, and disabled optional curl, expat, OpenSSL, gettext, iconv, Perl, Python and Tcl/Tk features for these local validation builds.
Those build settings are not changes in this PR.

I performed the following checks:

  • I ran the expanded t2031-checkout-long-paths.sh suite against both binaries. Against the unmodified code, four of this PR's new cases fail with Result too large at 260/261 bytes. Against the patched code, all 14 tests pass with no skips: the seven pre-existing tests, the new setup test and the six new regression cases.
  • I reran the existing PowerShell reproducer, which was published before this PR and is not modified or added to the repository by this PR. Its 13 cases complete with both binaries. The unmodified binary produces eight conversion errors on stderr; the patched binary produces no errors or differences. Both script processes exit 0, so I checked stderr explicitly.
  • I ran five other existing, unchanged test scripts against the patched code: t0060-path-utils.sh, t2007-checkout-symlink.sh, t2102-update-index-symlinks.sh, t4011-diff-symlink.sh and t7515-status-symlinks.sh. Together, they execute 219 tests successfully and skip 20 according to their prerequisites. This host's shell ln lacks native symlink support; this PR's new regression cases use Windows mklink, and all six execute successfully.

read_reparse_point() limits its UTF-16 to UTF-8 conversion to MAX_PATH
bytes, although both callers provide a MAX_LONG_PATH-sized buffer. Since
the conversion includes the terminating NUL, symlink targets of 260 or
more UTF-8 bytes fail with ERANGE. This affects both readlink() and
mingw_lstat(), even for short link paths and with core.longpaths enabled.

Use MAX_LONG_PATH for the conversion, matching the buffers allocated by
the callers. Add Windows regression coverage for ASCII and multibyte
targets of 259, 260 and 261 bytes. Check the decoded target as well as the
diff output and stderr, since git diff can report the conversion error
without failing its exit status. Disable the filesystem cache so the
tests also exercise mingw_lstat().

Fixes: git-for-windows#6498
Co-authored-by: GPT-6
Signed-off-by: vgm <virgilming@gmail.com>

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression: symlink targets >= 260 UTF-8 bytes fail with "Result too large" despite core.longpaths=true

1 participant