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

LibVT: Always check intermediate bytes in CSI sequences

Previously, we only checked the intermediate bytes for those escape
sequences that performed different operations based on their
intermediate bytes. This lead to a crash when `CSI ?1001 r` was
incorrectly parsed as `CSI Pt ; Pb r` (note the missing question mark),
as seen in #8559.
This commit is contained in:
Daniel Bertalan 2021-07-09 12:08:36 +02:00 committed by Ali Mohammad Pur
parent 52aa777d49
commit 0e04f7cf1e
2 changed files with 201 additions and 213 deletions

View file

@ -48,7 +48,19 @@ void Terminal::clear_history()
}
#endif
void Terminal::alter_mode(bool should_set, Parameters params, Intermediates intermediates)
void Terminal::alter_ansi_mode(bool should_set, Parameters params)
{
for (auto mode : params) {
switch (mode) {
// FIXME: implement *something* for this
default:
dbgln("Terminal::alter_ansi_mode: Unimplemented mode {} (should_set={})", mode, should_set);
break;
}
}
}
void Terminal::alter_private_mode(bool should_set, Parameters params)
{
auto steady_cursor_to_blinking = [](CursorStyle style) {
switch (style) {
@ -76,7 +88,6 @@ void Terminal::alter_mode(bool should_set, Parameters params, Intermediates inte
}
};
if (intermediates.size() > 0 && intermediates[0] == '?') {
for (auto mode : params) {
switch (mode) {
case 3: {
@ -153,30 +164,30 @@ void Terminal::alter_mode(bool should_set, Parameters params, Intermediates inte
m_needs_bracketed_paste = should_set;
break;
default:
dbgln("Terminal::alter_mode: Unimplemented private mode {} (should_set={})", mode, should_set);
break;
}
}
} else {
for (auto mode : params) {
switch (mode) {
// FIXME: implement *something* for this
default:
dbgln("Terminal::alter_mode: Unimplemented mode {} (should_set={})", mode, should_set);
dbgln("Terminal::alter_private_mode: Unimplemented private mode {} (should_set={})", mode, should_set);
break;
}
}
}
void Terminal::RM(Parameters params)
{
alter_ansi_mode(false, params);
}
void Terminal::RM(Parameters params, Intermediates intermediates)
void Terminal::DECRST(Parameters params)
{
alter_mode(false, params, intermediates);
alter_private_mode(false, params);
}
void Terminal::SM(Parameters params, Intermediates intermediates)
void Terminal::SM(Parameters params)
{
alter_mode(true, params, intermediates);
alter_ansi_mode(true, params);
}
void Terminal::DECSET(Parameters params)
{
alter_private_mode(true, params);
}
void Terminal::SGR(Parameters params)
@ -1085,124 +1096,95 @@ void Terminal::execute_csi_sequence(Parameters parameters, Intermediates interme
if (ignore)
dbgln("CSI sequence has its ignore flag set.");
if (intermediates.is_empty()) {
switch (last_byte) {
case '@':
ICH(parameters);
break;
return ICH(parameters);
case 'A':
CUU(parameters);
break;
return CUU(parameters);
case 'B':
CUD(parameters);
break;
return CUD(parameters);
case 'C':
CUF(parameters);
break;
return CUF(parameters);
case 'D':
CUB(parameters);
break;
return CUB(parameters);
case 'E':
CNL(parameters);
break;
return CNL(parameters);
case 'F':
CPL(parameters);
break;
return CPL(parameters);
case 'G':
CHA(parameters);
break;
return CHA(parameters);
case 'H':
CUP(parameters);
break;
return CUP(parameters);
case 'J':
ED(parameters);
break;
return ED(parameters);
case 'K':
EL(parameters);
break;
return EL(parameters);
case 'L':
IL(parameters);
break;
return IL(parameters);
case 'M':
DL(parameters);
break;
return DL(parameters);
case 'P':
DCH(parameters);
break;
return DCH(parameters);
case 'S':
SU(parameters);
break;
return SU(parameters);
case 'T':
SD(parameters);
break;
return SD(parameters);
case 'X':
ECH(parameters);
break;
return ECH(parameters);
case '`':
HPA(parameters);
break;
return HPA(parameters);
case 'a':
HPR(parameters);
break;
return HPR(parameters);
case 'b':
REP(parameters);
break;
return REP(parameters);
case 'c':
DA(parameters);
break;
return DA(parameters);
case 'd':
VPA(parameters);
break;
return VPA(parameters);
case 'e':
VPR(parameters);
break;
return VPR(parameters);
case 'f':
HVP(parameters);
break;
return HVP(parameters);
case 'h':
SM(parameters, intermediates);
break;
return SM(parameters);
case 'l':
RM(parameters, intermediates);
break;
return RM(parameters);
case 'm':
SGR(parameters);
break;
return SGR(parameters);
case 'n':
DSR(parameters);
break;
case 'q':
if (intermediates.size() >= 1 && intermediates[0] == ' ')
DECSCUSR(parameters);
else
unimplemented_csi_sequence(parameters, intermediates, last_byte);
break;
return DSR(parameters);
case 'r':
DECSTBM(parameters);
break;
return DECSTBM(parameters);
case 's':
SCOSC();
break;
return SCOSC();
case 't':
XTERM_WM(parameters);
break;
return XTERM_WM(parameters);
case 'u':
SCORC();
break;
case '}':
if (intermediates.size() >= 1 && intermediates[0] == '\'')
DECIC(parameters);
else
unimplemented_csi_sequence(parameters, intermediates, last_byte);
break;
case '~':
if (intermediates.size() >= 1 && intermediates[0] == '\'')
DECDC(parameters);
else
unimplemented_csi_sequence(parameters, intermediates, last_byte);
break;
default:
unimplemented_csi_sequence(parameters, intermediates, last_byte);
return SCORC();
}
} else if (intermediates.size() == 1 && intermediates[0] == '?') {
switch (last_byte) {
case 'h':
return DECSET(parameters);
case 'l':
return DECRST(parameters);
}
} else if (intermediates.size() == 1 && intermediates[0] == '\'') {
switch (last_byte) {
case '}':
return DECIC(parameters);
case '~':
return DECDC(parameters);
}
} else if (intermediates.size() == 1 && intermediates[0] == ' ') {
switch (last_byte) {
case 'q':
return DECSCUSR(parameters);
}
}
unimplemented_csi_sequence(parameters, intermediates, last_byte);
}
void Terminal::execute_osc_sequence(OscParameters parameters, u8 last_byte)
@ -1603,5 +1585,4 @@ Attribute Terminal::attribute_at(const Position& position) const
return line.attribute_at(position.column());
}
#endif
}

View file

@ -226,7 +226,8 @@ protected:
void emit_string(const StringView&);
void alter_mode(bool should_set, Parameters, Intermediates);
void alter_ansi_mode(bool should_set, Parameters);
void alter_private_mode(bool should_set, Parameters);
// CUU Cursor Up
void CUU(Parameters);
@ -274,10 +275,16 @@ protected:
void DECSTBM(Parameters);
// RM Reset Mode
void RM(Parameters, Intermediates);
void RM(Parameters);
// DECRST - DEC Private Mode Reset
void DECRST(Parameters);
// SM Set Mode
void SM(Parameters, Intermediates);
void SM(Parameters);
// DECSET - Dec Private Mode Set
void DECSET(Parameters);
// DA - Device Attributes
void DA(Parameters);