From: Yasuhiro Matsumoto Date: Sun, 22 Mar 2026 17:05:14 +0000 (+0000) Subject: patch 9.2.0227: MS-Windows: CSI sequences may be written to screen X-Git-Tag: v9.2.0227^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aeb716ea77d4fbb43cf3e2e787d4b1dd5ea8366a;p=thirdparty%2Fvim.git patch 9.2.0227: MS-Windows: CSI sequences may be written to screen Problem: MS-Windows: CSI sequences may be written to screen (after v9.2.0200). Solution: Move the CSI parsing and skipping logic outside of the USE_VTP guard in mch_write() so that sequences are always consumed even if VTP is inactive (Yasuhiro Matsumoto). After v9.2.0200 added send_decrqm_modes(), running vim -u NONE -U NONE -N on Windows displays raw ESC[?2026$p on screen. This is because USE_VTP is false when termguicolors is off and t_colors < 256, and the CSI skip logic in mch_write() was inside the if (USE_VTP) block, so s/len were never advanced and the escape sequence leaked out as plain text. Move the CSI parsing/skipping outside the USE_VTP guard so sequences are always consumed. Only the vtp_printf() pass-through for DECSCUSR (q) remains conditional on USE_VTP. related: #19755 closes: #19762 Signed-off-by: Yasuhiro Matsumoto Signed-off-by: Christian Brabandt --- diff --git a/src/os_win32.c b/src/os_win32.c index 0174068f01..e24c40cf31 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -7440,30 +7440,25 @@ notsgr: } else if (s[0] == ESC && len >= 3-1 && s[1] == '[') { - // When USE_VTP is active, CSI sequences written through - // write_chars() are interpreted by the console's VTP parser, - // generating responses (e.g. DECRQM) that end up in the - // input buffer as unwanted keystrokes. Parse the sequence - // and only pass through known safe ones (e.g. DECSCUSR for - // cursor shape), discard the rest. - if (USE_VTP) + // CSI sequences should not be written as plain text to the + // console. Parse the sequence and skip over it. When + // USE_VTP is active, pass through known safe ones (e.g. + // DECSCUSR for cursor shape) via vtp_printf(). + int l = 2; + + // skip parameter and intermediate bytes (0x20-0x3F) + while (s + l < end && s[l] >= 0x20 && s[l] <= 0x3F) + l++; + // skip the final byte (0x40-0x7E) + if (s + l < end && s[l] >= 0x40 && s[l] <= 0x7E) { - int l = 2; - - // skip parameter and intermediate bytes (0x20-0x3F) - while (s + l < end && s[l] >= 0x20 && s[l] <= 0x3F) - l++; - // skip the final byte (0x40-0x7E) - if (s + l < end && s[l] >= 0x40 && s[l] <= 0x7E) - { - // DECSCUSR (cursor style): pass through to terminal - if (s[l] == 'q') - vtp_printf("%.*s", l + 1, s); - l++; - } - len -= l - 1; - s += l; + // DECSCUSR (cursor style): pass through to terminal + if (USE_VTP && s[l] == 'q') + vtp_printf("%.*s", l + 1, s); + l++; } + len -= l - 1; + s += l; } else { diff --git a/src/version.c b/src/version.c index f5693b6a7f..ca86462ff0 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 227, /**/ 226, /**/