Skip to content

[msys2-runtime] fhandler_console drops one character at each 32 KiB conversion boundary #6388

Description

@FlyaiF

Existing issues matching what you're seeing

  • I was not able to find an open or closed issue matching what I'm seeing

Git for Windows version

git version 2.55.0.windows.3
cpu: x86_64
built from commit: 52ca1113d651127f89477a8763f86ab20f645e1d
sizeof-long: 4
sizeof-size_t: 8
shell-path: D:/git-sdk-64/usr/bin/sh
rust: disabled
feature: fsmonitor--daemon
gettext: enabled
libcurl: 8.21.0
OpenSSL: OpenSSL 3.5.7 9 Jun 2026
zlib: 1.3.2
SHA-1: SHA1_DC
SHA-256: SHA256_BLK
default-ref-format: files
default-hash: sha1

Windows version

Windows 11

Windows CPU architecture

x86_64 (64-bit)

Additional Windows version information

Microsoft Windows [Version 10.0.22631.7517]

Options set during installation

PS C:\Users\hongxd43274> type "C:\Program Files\Git\etc\install-options.txt"
Editor Option: VIM
Custom Editor Path:
Default Branch Option:
Path Option: Cmd
SSH Option: OpenSSH
Tortoise Option: false
CURL Option: WinSSL
CRLF Option: CRLFAlways
Bash Terminal Option: MinTTY
Git Pull Behavior Option: Merge
Use Credential Manager: Enabled
Performance Tweaks FSCache: Enabled
Enable Symlinks: Disabled
Enable FSMonitor: Disabled

Other interesting things

Windows Terminal package: 1.24.11911.0 (x64)
MSYS runtime: 3.6.9-b4195d69.x86_64, built 2026-06-06 17:49 UTC
/usr/bin/ssh.exe: OpenSSH_10.3p1, OpenSSL 3.5.7 9 Jun 2026

Terminal/shell

Git Bash (C:\Program Files\Git\bin\bash.exe -l) hosted by Windows Terminal/ConPTY. Stdout must remain attached directly to the terminal.

Commands that trigger the issue

LC_ALL=C awk 'BEGIN {
    pattern = "123456789abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz"
    for (line = 1; line <= 5000; line++)
        printf "%08d %s\n", line, pattern
}' >/tmp/msys-console-repro.txt

wc -c /tmp/msys-console-repro.txt
sha256sum /tmp/msys-console-repro.txt

dd if=/tmp/msys-console-repro.txt bs=32768 status=none

Expected behaviour

all output line should be "123456789abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz"

Actual behaviour

Image With the unmodified runtime, one character is discarded at each 32768-byte conversion boundary. In the 400,000-byte reproduction, 12 numbered lines are malformed; when a discarded character is a newline, two numbered lines appear merged.

The loss occurs before Windows Terminal receives or renders the output. It is also observable through the Windows console screen buffer, and the two-part runtime patch eliminates it.

Repository

CONVERT_LIMIT is currently NT_MAX_PATH (32768). For an ASCII span of exactly 32768 bytes, fhandler_console::write_normal() advances over all 32768 input bytes and calls _sys_mbstowcs() with a destination length of 32768.

_sys_mbstowcs() converts 32768 characters, then reserves space for its trailing NUL by clamping the returned count to dlen - 1 and storing L'\0' at that position:

count = (count < dlen) ? count : dlen - 1;
dst[count] = L'\0';

The last converted character is therefore overwritten and only 32767 characters are passed to WriteConsoleW(), while write_normal() has already consumed 32768 input bytes. The missing input byte is never retried. With ASCII output, this repeats at each 32768-byte conversion boundary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions