ui/console-vc: ignore string-type escape sequences
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 \). Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Marc-André Lureau committed
Mar 12, 2026 at 17:35 UTC
a53a41a5451c563d19b340ad538ee8df09b0ed71
1 file changed
+15
ui/console-vc.c
+15
@@ -44,6 +44,7 @@ enum TTYState {
44
TTY_STATE_CSI,
45
TTY_STATE_G0,
46
TTY_STATE_G1,
47
+ TTY_STATE_OSC,
48
};
49
50
typedef struct QemuTextConsole {
@@ -807,6 +808,10 @@ static void vc_putchar(VCChardev *vc, int ch)
808
vc->state = TTY_STATE_G0;
809
} else if (ch == ')') {
810
vc->state = TTY_STATE_G1;
811
+ } else if (ch == ']' || ch == 'P' || ch == 'X'
812
+ || ch == '^' || ch == '_') {
813
+ /* String sequences: OSC, DCS, SOS, PM, APC */
814
+ vc->state = TTY_STATE_OSC;
815
} else if (ch == '7') {
816
vc_save_cursor(vc);
817
vc->state = TTY_STATE_NORM;
@@ -965,6 +970,16 @@ static void vc_putchar(VCChardev *vc, int ch)
970
break;
971
}
972
break;
973
+ case TTY_STATE_OSC: /* Operating System Command: ESC ] ... BEL/ST */
974
+ if (ch == '\a') {
975
+ /* BEL terminates OSC */
976
+ vc->state = TTY_STATE_NORM;
977
+ } else if (ch == 27) {
978
+ /* ESC might start ST (ESC \) */
979
+ vc->state = TTY_STATE_ESC;
980
+ }
981
+ /* All other bytes are silently consumed */
982
+ break;
983
case TTY_STATE_G0: /* set character sets */
984
case TTY_STATE_G1: /* set character sets */
985
switch (ch) {