1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 14:17:45 +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;
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; bool ok;
unsigned value = String::copy(m_xterm_param1).to_uint(ok); unsigned value = parampart.to_uint(ok);
if (ok) { numeric_params.append(ok ? value : 0);
switch (value) { }
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 0:
case 1: case 1:
case 2: case 2:
m_client.set_window_title(String::copy(m_xterm_param2)); m_client.set_window_title(params[1]);
break; break;
default: default:
unimplemented_xterm_escape(); unimplemented_xterm_escape();
break; 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; return;
case ExpectXtermParameter1: case ExpectXtermParameter:
if (ch != ';') { if (ch == 27) {
m_xterm_param1.append(ch); m_escape_state = ExpectStringTerminator;
return; return;
} }
m_escape_state = ExpectXtermParameter2; if (ch == 7) {
return;
case ExpectXtermParameter2:
if (ch != '\007') {
m_xterm_param2.append(ch);
return;
}
m_escape_state = ExpectXtermFinal;
[[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 };