diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index c1f152d8b03b..16010bbc76d7 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1644,9 +1644,7 @@ static void rgb_background(struct vc_data *vc, const struct rgb *c) /* * ITU T.416 Higher colour modes. They break the usual properties of SGR codes - * and thus need to be detected and ignored by hand. That standard also - * wants : rather than ; as separators but sequences containing : are currently - * completely ignored by the parser. + * and thus need to be detected and ignored by hand. * * Subcommands 3 (CMY) and 4 (CMYK) are so insane there's no point in * supporting them. @@ -1703,6 +1701,7 @@ enum { CSI_m_BG_COLOR_END = 47, CSI_m_BG_COLOR = 48, CSI_m_DEFAULT_BG_COLOR = 49, + CSI_m_UNDERLINE_COLOR = 58, CSI_m_BRIGHT_FG_COLOR_BEG = 90, CSI_m_BRIGHT_FG_COLOR_END = 97, CSI_m_BRIGHT_FG_COLOR_OFF = CSI_m_BRIGHT_FG_COLOR_BEG - CSI_m_FG_COLOR_BEG, @@ -2160,6 +2159,7 @@ static void restore_cur(struct vc_data *vc) * @ESesc: ESC parsed * @ESsquare: CSI parsed -- modifiers/parameters/ctrl chars expected * @ESgetpars: CSI parsed -- parameters/ctrl chars expected + * @ESgetsubpars: CSI m parsed -- subparameters expected * @ESfunckey: CSI [ parsed * @EShash: ESC # parsed * @ESsetG0: ESC ( parsed @@ -2180,6 +2180,7 @@ enum vc_ctl_state { ESesc, ESsquare, ESgetpars, + ESgetsubpars, ESfunckey, EShash, ESsetG0, @@ -2699,6 +2700,47 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c) fallthrough; case ESgetpars: /* ESC [ aka CSI, parameters expected */ switch (c) { + case ':': /* ITU-T T.416 color subparameters */ + if (vc->vc_par[vc->vc_npar] == CSI_m_FG_COLOR || + vc->vc_par[vc->vc_npar] == CSI_m_BG_COLOR || + vc->vc_par[vc->vc_npar] == CSI_m_UNDERLINE_COLOR) + vc->vc_state = ESgetsubpars; + else + break; + fallthrough; + case ';': + if (vc->vc_npar < NPAR - 1) { + vc->vc_npar++; + return; + } + break; + case '0' ... '9': + vc->vc_par[vc->vc_npar] *= 10; + vc->vc_par[vc->vc_npar] += c - '0'; + return; + } + if (c >= ASCII_CSI_IGNORE_FIRST && c <= ASCII_CSI_IGNORE_LAST) { + vc->vc_state = EScsiignore; + return; + } + + /* parameters done, handle the control char @c */ + + vc->vc_state = ESnormal; + + switch (vc->vc_priv) { + case EPdec: + csi_DEC(tty, vc, c); + return; + case EPecma: + csi_ECMA(tty, vc, c); + return; + default: + return; + } + case ESgetsubpars: /* ESC [ 38/48/58, subparameters expected */ + switch (c) { + case ':': case ';': if (vc->vc_npar < NPAR - 1) { vc->vc_npar++;