From c6013e2969ba88cb5a54b15a14615ff359bd411f Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 19 Oct 2023 18:55:04 +0100 Subject: [PATCH] Recognise and discard the APC terminal escape sequence. I encountered an instance of this sequence in the log files from a clang CI build. The payload text inside the wrapper was "bk;t=1697630539879"; I don't know what the "bk" stood for, but the second half appears to be a timestamp in milliseconds since the Unix epoch. I don't think there's anything we can (or should) actually _do_ with this sequence, but I think it's useful to at least recognise it, so that it can be conveniently discarded. (cherry picked from commit 7b10e34b8f636008243df1a1add61c0763befb38) --- terminal/terminal.c | 22 ++++++++++++++++++++++ terminal/terminal.h | 1 + 2 files changed, 23 insertions(+) diff --git a/terminal/terminal.c b/terminal/terminal.c index 3cdfc0d4..90c2880d 100644 --- a/terminal/terminal.c +++ b/terminal/terminal.c @@ -3206,6 +3206,13 @@ static void toggle_mode(Terminal *term, int mode, int query, bool state) */ static void do_osc(Terminal *term) { + if (term->osc_is_apc) { + /* This OSC was really an APC, and we don't support that + * sequence at all. We only recognise it in order to ignore it + * and filter it out of input. */ + return; + } + if (term->osc_w) { while (term->osc_strlen--) term->wordness[(unsigned char)term->osc_string[term->osc_strlen]] = @@ -4134,6 +4141,21 @@ static void term_out(Terminal *term, bool called_from_term_data) /* Compatibility is nasty here, xterm, linux, decterm yuk! */ compatibility(OTHER); term->termstate = SEEN_OSC; + term->osc_is_apc = false; + term->osc_strlen = 0; + term->esc_args[0] = 0; + term->esc_nargs = 1; + break; + case '_': /* APC: application program command */ + /* APC sequences are just a string, terminated by + * ST or (I've observed in practice) ^G. That is, + * they have the same termination convention as + * OSC. So we handle them by going straight into + * OSC_STRING state and setting a flag indicating + * that it's not really an OSC. */ + compatibility(OTHER); + term->termstate = SEEN_OSC; + term->osc_is_apc = true; term->osc_strlen = 0; term->esc_args[0] = 0; term->esc_nargs = 1; diff --git a/terminal/terminal.h b/terminal/terminal.h index d00133b9..e0361313 100644 --- a/terminal/terminal.h +++ b/terminal/terminal.h @@ -183,6 +183,7 @@ struct terminal_tag { #define ANSI_QUE(x) ANSI(x,1) #define OSC_STR_MAX 2048 + bool osc_is_apc; int osc_strlen; char osc_string[OSC_STR_MAX + 1]; bool osc_w;