diff options
author | Andreas Kling <kling@serenityos.org> | 2020-05-09 12:08:41 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-09 12:08:41 +0200 |
commit | a0616d96bfa5ce3412c3e404316d4af13fbe6294 (patch) | |
tree | d693448f496a1ef6305c4315f0d64acdb6b0a1de /Libraries/LibVT | |
parent | 283bd1a95c4260a7e613de34f5a0f5e41e534b48 (diff) | |
download | serenity-a0616d96bfa5ce3412c3e404316d4af13fbe6294.zip |
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.
Diffstat (limited to 'Libraries/LibVT')
-rw-r--r-- | Libraries/LibVT/Terminal.cpp | 76 | ||||
-rw-r--r-- | Libraries/LibVT/Terminal.h | 9 |
2 files changed, 50 insertions, 35 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() { + 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 = '@'; - 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; - } + + 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; + case ExpectXtermParameter: + if (ch == 27) { + m_escape_state = ExpectStringTerminator; return; } - m_escape_state = ExpectXtermParameter2; - return; - case ExpectXtermParameter2: - if (ch != '\007') { - m_xterm_param2.append(ch); + if (ch == 7) { + execute_xterm_command(); + m_escape_state = Normal; return; } - m_escape_state = ExpectXtermFinal; - [[fallthrough]]; - case ExpectXtermFinal: - m_escape_state = Normal; - if (ch == '\007') + 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<u8> m_parameters; Vector<u8> m_intermediates; - Vector<u8> m_xterm_param1; - Vector<u8> m_xterm_param2; + Vector<u8> m_xterm_parameters; Vector<bool> m_horizontal_tabs; u8 m_final { 0 }; |