summaryrefslogtreecommitdiff
path: root/Libraries/LibVT
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-05-09 12:08:41 +0200
committerAndreas Kling <kling@serenityos.org>2020-05-09 12:08:41 +0200
commita0616d96bfa5ce3412c3e404316d4af13fbe6294 (patch)
treed693448f496a1ef6305c4315f0d64acdb6b0a1de /Libraries/LibVT
parent283bd1a95c4260a7e613de34f5a0f5e41e534b48 (diff)
downloadserenity-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.cpp76
-rw-r--r--Libraries/LibVT/Terminal.h9
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 };