From f2b361c1463371ac2be681235470343ae48c23b5 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Mon, 12 Sep 2022 20:11:45 +0100 Subject: [PATCH] Make sure Terminal state machine always accepts C1 controls (#13969) When we added support for the `DECAC1` control sequence, which determines whether `C1` controls are accepted or not, the intention was that conhost would be making that determination, and Windows Terminal would always be expected to accept any passed-through `C1` controls. However, this didn't take into account that a passed-through `RIS` sequence could end up disabling `DECAC1`, and that would leave Windows Terminal incapable of processing any `C1` controls. This PR attempts to fix that oversight. The `DECAC1` sequence was added in PR #11690, when we disabled `C1` acceptance by default. This is a bit of a hack, but I've added a new `AlwaysAcceptC1` mode to the state machine, which is enabled at startup in the Terminal, and is never disabled. The parser then just needs to check whether either `AcceptC1` or `AlwaysAcceptC1` are set. ## Validation Steps Performed I've manually confirmed the test case in #13968 now works as expected. Closes #13968 --- src/cascadia/TerminalCore/Terminal.cpp | 2 +- src/terminal/parser/stateMachine.cpp | 2 +- src/terminal/parser/stateMachine.hpp | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 1cf4528a569..6e9a3be7b19 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -91,7 +91,7 @@ void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Re // But if they are being accepted by conhost, there's a chance they may get // passed through in some situations, so it's important that our state // machine is always prepared to accept them. - _stateMachine->SetParserMode(StateMachine::Mode::AcceptC1, true); + _stateMachine->SetParserMode(StateMachine::Mode::AlwaysAcceptC1, true); } // Method Description: diff --git a/src/terminal/parser/stateMachine.cpp b/src/terminal/parser/stateMachine.cpp index 21ee4a88efb..36848694f32 100644 --- a/src/terminal/parser/stateMachine.cpp +++ b/src/terminal/parser/stateMachine.cpp @@ -1716,7 +1716,7 @@ void StateMachine::ProcessCharacter(const wchar_t wch) // code points that get translated as C1 controls when that is not their // intended use. In order to avoid them triggering unintentional escape // sequences, we ignore these characters by default. - if (_parserMode.test(Mode::AcceptC1)) + if (_parserMode.any(Mode::AcceptC1, Mode::AlwaysAcceptC1)) { ProcessCharacter(AsciiChars::ESC); ProcessCharacter(_c1To7Bit(wch)); diff --git a/src/terminal/parser/stateMachine.hpp b/src/terminal/parser/stateMachine.hpp index c3c3936693b..41bce50f97e 100644 --- a/src/terminal/parser/stateMachine.hpp +++ b/src/terminal/parser/stateMachine.hpp @@ -50,6 +50,7 @@ namespace Microsoft::Console::VirtualTerminal enum class Mode : size_t { AcceptC1, + AlwaysAcceptC1, Ansi, };