fix: Skip grapheme cluster probe on Windows to prevent output corruption#1695
Merged
fix: Skip grapheme cluster probe on Windows to prevent output corruption#1695
Conversation
On Windows with Cygwin/MSYSTEM (Git Bash), the ExecTerminalProvider creates a PosixSysTerminal whose ExecPty slave output goes to a raw FileDescriptor (stdout/stderr) rather than a real PTY device. When probeGraphemeClusterMode() writes the DECRQM query (\e[?2027$p) to this raw fd, it contaminates the process output. Downstream consumers that parse stdout (e.g. Maven's ToolboxToolTest) then fail because paths get prefixed with the escape sequence. AbstractWindowsTerminal already overrides supportsGraphemeClusterMode() to return false, so this guard only affects the Cygwin/MSYSTEM PosixSysTerminal path where the probe cannot work correctly anyway. Fixes apache/maven#11774
Move the IS_WINDOWS check from AbstractTerminal.probeGraphemeClusterMode() to PosixSysTerminal.supportsGraphemeClusterMode() so that LineDisciplineTerminal-based tests (GraphemeClusterModeTest) are not affected on Windows.
Instead of blanket-disabling grapheme cluster mode on all Windows Cygwin/MSYSTEM terminals, only skip the probe when the ExecPty output stream is not actually connected to a terminal (e.g. piped in a subprocess). Interactive Cygwin/MSYSTEM terminals that support mode 2027 will still get grapheme cluster support.
gnodet
added a commit
that referenced
this pull request
Mar 11, 2026
The previous fix (#1695) only blocked the DECRQM probe when using ExecPty and the output stream was not detected as a system stream. This was insufficient because the isSystemStream() check is unreliable on Windows MSYSTEM environments — it can return true for streams that are being captured by a parent process. Simplify the guard to disable the probe entirely on Windows PosixSysTerminal. On Windows, PosixSysTerminal only exists for Cygwin/MSYSTEM environments where the slave output goes to a raw FileDescriptor, making the probe inherently risky.
2 tasks
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 free
to 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.
Summary
probeGraphemeClusterMode()on Windows to prevent escape sequence leakage into process outputProblem
On Windows with Cygwin/MSYSTEM (Git Bash), the
ExecTerminalProvidercreates aPosixSysTerminalwhoseExecPtyslave output goes to a rawFileDescriptor(stdout/stderr) rather than a real PTY device. WhenprobeGraphemeClusterMode()writes the DECRQM query (\e[?2027$p) to this raw fd, it contaminates the process output.This was discovered via the Maven JLine 4.0.2 upgrade where all Windows CI jobs fail with:
The
[?2027$pescape sequence leaks into stdout and gets prepended to paths that Maven parses.Fix
Added a guard in
AbstractTerminal.probeGraphemeClusterMode()to returnfalseon Windows. This is safe because:AbstractWindowsTerminalalready overridessupportsGraphemeClusterMode()to returnfalse— native Windows terminals are unaffectedprobeGraphemeClusterMode()on Windows is through the Cygwin/MSYSTEMPosixSysTerminal, where the probe output goes to a rawFileDescriptorrather than a real PTY deviceDoes not apply to
jline-3.x— the grapheme cluster mode 2027 feature was introduced only in the 4.x line.Test plan
GraphemeClusterModeTestpasses (usesLineDisciplineTerminal, not affected)