Modern terminals and applications emit OSC (Operating System Command), DCS, SOS, PM, and APC escape sequences (e.g. for setting window titles). The text console currently does not recognise these string-type introducers, so each byte of the payload is interpreted as a normal character or a new escape, producing garbage on screen.
Add a TTY_STATE_OSC state that silently consumes all bytes until the sequence is terminated by BEL or ST (ESC \). Signed-off-by: Marc-André Lureau <[email protected]> --- ui/console-vc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ui/console-vc.c b/ui/console-vc.c index 7bbd65dea27..5eca9a5c004 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -45,6 +45,7 @@ enum TTYState { TTY_STATE_CSI, TTY_STATE_G0, TTY_STATE_G1, + TTY_STATE_OSC, }; typedef struct QemuTextConsole { @@ -869,6 +870,10 @@ static void vc_putchar(VCChardev *vc, int ch) vc->state = TTY_STATE_G0; } else if (ch == ')') { vc->state = TTY_STATE_G1; + } else if (ch == ']' || ch == 'P' || ch == 'X' + || ch == '^' || ch == '_') { + /* String sequences: OSC, DCS, SOS, PM, APC */ + vc->state = TTY_STATE_OSC; } else if (ch == '7') { vc_save_cursor(vc); vc->state = TTY_STATE_NORM; @@ -1027,6 +1032,16 @@ static void vc_putchar(VCChardev *vc, int ch) break; } break; + case TTY_STATE_OSC: /* Operating System Command: ESC ] ... BEL/ST */ + if (ch == '\a') { + /* BEL terminates OSC */ + vc->state = TTY_STATE_NORM; + } else if (ch == 27) { + /* ESC might start ST (ESC \) */ + vc->state = TTY_STATE_ESC; + } + /* All other bytes are silently consumed */ + break; case TTY_STATE_G0: /* set character sets */ case TTY_STATE_G1: /* set character sets */ switch (ch) { -- 2.53.0
