1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 04:27:44 +00:00

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.
This commit is contained in:
Andreas Kling 2020-05-09 12:08:41 +02:00
parent 283bd1a95c
commit a0616d96bf
2 changed files with 52 additions and 37 deletions

View file

@ -577,23 +577,38 @@ void Terminal::escape$P(const ParamVector& params)
void Terminal::execute_xterm_command() void Terminal::execute_xterm_command()
{ {
m_final = '@'; ParamVector numeric_params;
bool ok; auto param_string = String::copy(m_xterm_parameters);
unsigned value = String::copy(m_xterm_param1).to_uint(ok); auto params = param_string.split(';', true);
if (ok) { m_xterm_parameters.clear_with_capacity();
switch (value) { for (auto& parampart : params) {
case 0: bool ok;
case 1: unsigned value = parampart.to_uint(ok);
case 2: numeric_params.append(ok ? value : 0);
m_client.set_window_title(String::copy(m_xterm_param2)); }
break;
default: while (params.size() < 3) {
unimplemented_xterm_escape(); params.append(String::empty());
break; 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) void Terminal::execute_escape_sequence(u8 final)
@ -835,7 +850,8 @@ void Terminal::on_char(u8 ch)
m_swallow_current = true; m_swallow_current = true;
m_escape_state = ExpectParameter; m_escape_state = ExpectParameter;
} else if (ch == ']') { } else if (ch == ']') {
m_escape_state = ExpectXtermParameter1; m_escape_state = ExpectXtermParameter;
m_xterm_parameters.clear_with_capacity();
} else if (ch == '#') { } else if (ch == '#') {
m_escape_state = ExpectHashtagDigit; m_escape_state = ExpectHashtagDigit;
} else if (ch == 'D') { } else if (ch == 'D') {
@ -860,25 +876,25 @@ void Terminal::on_char(u8 ch)
execute_hashtag(ch); execute_hashtag(ch);
m_escape_state = Normal; m_escape_state = Normal;
} }
break;
case ExpectXtermParameter1:
if (ch != ';') {
m_xterm_param1.append(ch);
return;
}
m_escape_state = ExpectXtermParameter2;
return; return;
case ExpectXtermParameter2: case ExpectXtermParameter:
if (ch != '\007') { if (ch == 27) {
m_xterm_param2.append(ch); m_escape_state = ExpectStringTerminator;
return; return;
} }
m_escape_state = ExpectXtermFinal; if (ch == 7) {
[[fallthrough]];
case ExpectXtermFinal:
m_escape_state = Normal;
if (ch == '\007')
execute_xterm_command(); 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; return;
case ExpectParameter: case ExpectParameter:
if (is_valid_parameter_character(ch)) { if (is_valid_parameter_character(ch)) {

View file

@ -211,15 +211,14 @@ private:
ExpectIntermediate, ExpectIntermediate,
ExpectFinal, ExpectFinal,
ExpectHashtagDigit, ExpectHashtagDigit,
ExpectXtermParameter1, ExpectXtermParameter,
ExpectXtermParameter2, ExpectStringTerminator,
ExpectXtermFinal,
}; };
EscapeState m_escape_state { Normal }; EscapeState m_escape_state { Normal };
Vector<u8> m_parameters; Vector<u8> m_parameters;
Vector<u8> m_intermediates; Vector<u8> m_intermediates;
Vector<u8> m_xterm_param1; Vector<u8> m_xterm_parameters;
Vector<u8> m_xterm_param2;
Vector<bool> m_horizontal_tabs; Vector<bool> m_horizontal_tabs;
u8 m_final { 0 }; u8 m_final { 0 };