From ed022e89db37fce34d298187ce2cf75c77b8ee74 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 3 Jul 2025 01:49:33 +0200 Subject: [PATCH] Fix another VT input double-encoding issue (#19083) Closes #17264 Closes https://github.com/microsoft/edit/issues/182 Long shot, but probably also... Closes #18579 Closes #19082 (cherry picked from commit 97f0a06fbe0d01521c14e7b1461faea2e5a83d5a) Service-Card-Id: PVTI_lADOAF3p4s4AxadtzgdOWF0 Service-Version: 1.23 --- src/terminal/adapter/InteractDispatch.cpp | 33 +++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/terminal/adapter/InteractDispatch.cpp b/src/terminal/adapter/InteractDispatch.cpp index 09cc2c970c..8ed76b9d7c 100644 --- a/src/terminal/adapter/InteractDispatch.cpp +++ b/src/terminal/adapter/InteractDispatch.cpp @@ -62,15 +62,38 @@ void InteractDispatch::WriteString(const std::wstring_view string) { if (!string.empty()) { - const auto codepage = _api.GetOutputCodePage(); - InputEventQueue keyEvents; + const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); +#pragma warning(suppress : 26429) // Symbol 'inputBuffer' is never tested for nullness, it can be marked as not_null (f.23). + const auto inputBuffer = gci.GetActiveInputBuffer(); - for (const auto& wch : string) + // The input *may* be keyboard input in which case we must call CharToKeyEvents. + // + // However, it could also be legitimate VT sequences (e.g. a bracketed paste sequence). + // If we called `InputBuffer::Write` with those, we would end up indirectly + // calling `TerminalInput::HandleKey` and "double encode" the sequence. + // The effect of this is noticeable with the German keyboard layout, for instance, + // where the [ key maps to AltGr+8, and we fail to map it back to [ later. + // + // It's worth noting that all of this is bad design in either case. + // The way it should work is that we write INPUT_RECORDs and Strings as-is into the + // InputBuffer, and only during retrieval they're converted into one or the other. + // This prevents any kinds of double-encoding issues. + if (inputBuffer->IsInVirtualTerminalInputMode()) { - CharToKeyEvents(wch, codepage, keyEvents); + inputBuffer->WriteString(string); } + else + { + const auto codepage = _api.GetOutputCodePage(); + InputEventQueue keyEvents; - WriteInput(keyEvents); + for (const auto& wch : string) + { + CharToKeyEvents(wch, codepage, keyEvents); + } + + inputBuffer->Write(keyEvents); + } } }