From a0616d96bfa5ce3412c3e404316d4af13fbe6294 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 9 May 2020 12:08:41 +0200 Subject: [PATCH] LibVT: Make the Xterm/OSC sequence parsing a bit more robust Tolerate sequences ending in both <0x07> (BEL) and <0x1b> <0x5c> (ST). The former is apparently an Xterm extension and the latter is standard. --- Libraries/LibVT/Terminal.cpp | 80 +++++++++++++++++++++--------------- Libraries/LibVT/Terminal.h | 9 ++-- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/Libraries/LibVT/Terminal.cpp b/Libraries/LibVT/Terminal.cpp index 690b0fd1d3..5da3ccc751 100644 --- a/Libraries/LibVT/Terminal.cpp +++ b/Libraries/LibVT/Terminal.cpp @@ -577,23 +577,38 @@ void Terminal::escape$P(const ParamVector& params) void Terminal::execute_xterm_command() { - m_final = '@'; - bool ok; - unsigned value = String::copy(m_xterm_param1).to_uint(ok); - if (ok) { - switch (value) { - case 0: - case 1: - case 2: - m_client.set_window_title(String::copy(m_xterm_param2)); - break; - default: - unimplemented_xterm_escape(); - break; - } + ParamVector numeric_params; + auto param_string = String::copy(m_xterm_parameters); + auto params = param_string.split(';', true); + m_xterm_parameters.clear_with_capacity(); + for (auto& parampart : params) { + bool ok; + unsigned value = parampart.to_uint(ok); + numeric_params.append(ok ? value : 0); + } + + while (params.size() < 3) { + params.append(String::empty()); + numeric_params.append(0); + } + + m_final = '@'; + + if (numeric_params.is_empty()) { + dbg() << "Empty Xterm params?"; + return; + } + + switch (numeric_params[0]) { + case 0: + case 1: + case 2: + m_client.set_window_title(params[1]); + break; + default: + unimplemented_xterm_escape(); + break; } - m_xterm_param1.clear_with_capacity(); - m_xterm_param2.clear_with_capacity(); } void Terminal::execute_escape_sequence(u8 final) @@ -835,7 +850,8 @@ void Terminal::on_char(u8 ch) m_swallow_current = true; m_escape_state = ExpectParameter; } else if (ch == ']') { - m_escape_state = ExpectXtermParameter1; + m_escape_state = ExpectXtermParameter; + m_xterm_parameters.clear_with_capacity(); } else if (ch == '#') { m_escape_state = ExpectHashtagDigit; } else if (ch == 'D') { @@ -860,25 +876,25 @@ void Terminal::on_char(u8 ch) execute_hashtag(ch); m_escape_state = Normal; } - break; - case ExpectXtermParameter1: - if (ch != ';') { - m_xterm_param1.append(ch); - return; - } - m_escape_state = ExpectXtermParameter2; return; - case ExpectXtermParameter2: - if (ch != '\007') { - m_xterm_param2.append(ch); + case ExpectXtermParameter: + if (ch == 27) { + m_escape_state = ExpectStringTerminator; return; } - m_escape_state = ExpectXtermFinal; - [[fallthrough]]; - case ExpectXtermFinal: - m_escape_state = Normal; - if (ch == '\007') + if (ch == 7) { execute_xterm_command(); + m_escape_state = Normal; + return; + } + m_xterm_parameters.append(ch); + return; + case ExpectStringTerminator: + if (ch == '\\') + execute_xterm_command(); + else + dbg() << "Unexpected string terminator: " << String::format("%02x", ch); + m_escape_state = Normal; return; case ExpectParameter: if (is_valid_parameter_character(ch)) { diff --git a/Libraries/LibVT/Terminal.h b/Libraries/LibVT/Terminal.h index 4d704da89b..9d31c4640b 100644 --- a/Libraries/LibVT/Terminal.h +++ b/Libraries/LibVT/Terminal.h @@ -211,15 +211,14 @@ private: ExpectIntermediate, ExpectFinal, ExpectHashtagDigit, - ExpectXtermParameter1, - ExpectXtermParameter2, - ExpectXtermFinal, + ExpectXtermParameter, + ExpectStringTerminator, }; + EscapeState m_escape_state { Normal }; Vector m_parameters; Vector m_intermediates; - Vector m_xterm_param1; - Vector m_xterm_param2; + Vector m_xterm_parameters; Vector m_horizontal_tabs; u8 m_final { 0 };