degesch: resolve the issue with less(1) and SO/SI

Now that I've learnt what exactly these characters are and how they
ended up in attribute strings, we can just eliminate them and disable
`backlog_helper_strip_formatting`.  Saner defaults, again.

I've also added skipping of terminfo delay sequences, so now it's less
of an issue to pipe raw attribute sequences into backlog helpers.
This commit is contained in:
Přemysl Eric Janouch 2020-10-04 12:04:24 +02:00
parent 9819b75b64
commit f665f147ff
Signed by: p
GPG Key ID: A0420B94F92B9493

View File

@ -2445,11 +2445,6 @@ static struct config_schema g_config_behaviour[] =
.default_ = "off", .default_ = "off",
.on_change = on_config_debug_mode_change }, .on_change = on_config_debug_mode_change },
// GNU screen has an ^O in its formatting attributes reset string,
// therefore we can't just pipe raw formatting to `less -R`.
// You can use the -r switch, however that makes `less` very confused
// about line wrapping, and the result is suboptimal.
{ .name = "backlog_limit", { .name = "backlog_limit",
.comment = "Maximum number of lines stored in the backlog", .comment = "Maximum number of lines stored in the backlog",
.type = CONFIG_ITEM_INTEGER, .type = CONFIG_ITEM_INTEGER,
@ -2463,7 +2458,7 @@ static struct config_schema g_config_behaviour[] =
{ .name = "backlog_helper_strip_formatting", { .name = "backlog_helper_strip_formatting",
.comment = "Strip formatting from backlog helper input", .comment = "Strip formatting from backlog helper input",
.type = CONFIG_ITEM_BOOLEAN, .type = CONFIG_ITEM_BOOLEAN,
.default_ = "on" }, .default_ = "off" },
{ .name = "reconnect_delay_growing", { .name = "reconnect_delay_growing",
.comment = "Growing factor for reconnect delay", .comment = "Growing factor for reconnect delay",
@ -2784,6 +2779,26 @@ struct attr_printer
#define ATTR_PRINTER_INIT(ctx, stream) { ctx->attrs, stream, true } #define ATTR_PRINTER_INIT(ctx, stream) { ctx->attrs, stream, true }
static void
attr_printer_filtered_puts (FILE *stream, const char *attr)
{
for (; *attr; attr++)
{
// sgr/set_attributes and sgr0/exit_attribute_mode like to enable or
// disable the ACS with SO/SI (e.g. for TERM=screen), however `less -R`
// does not skip over these characters and it screws up word wrapping
if (*attr == 14 /* SO */ || *attr == 15 /* SI */)
continue;
// Trivially skip delay sequences intended to be processed by tputs()
const char *end = NULL;
if (attr[0] == '$' && attr[1] == '<' && (end = strchr (attr, '>')))
attr = end;
else
fputc (*attr, stream);
}
}
static void static void
attr_printer_tputs (struct attr_printer *self, const char *attr) attr_printer_tputs (struct attr_printer *self, const char *attr)
{ {
@ -2791,9 +2806,9 @@ attr_printer_tputs (struct attr_printer *self, const char *attr)
if (printer) if (printer)
tputs (attr, 1, printer); tputs (attr, 1, printer);
else else
// We shouldn't really do this but we need it to // We shouldn't really do this but we need it to output formatting
// output formatting to the backlog // to the backlog helper--it should be SGR-only
fputs (attr, self->stream); attr_printer_filtered_puts (self->stream, attr);
} }
static void static void
@ -3604,7 +3619,7 @@ explode_text (struct exploder *self, const char *text)
// Throw away any potentially harmful control characters first // Throw away any potentially harmful control characters first
struct str filtered = str_make (); struct str filtered = str_make ();
for (const char *p = text; *p; p++) for (const char *p = text; *p; p++)
if (!strchr ("\a\b\x1b", *p)) if (!strchr ("\a\b\x0e\x0f\x1b" /* BEL BS SO SI ESC */, *p))
str_append_c (&filtered, *p); str_append_c (&filtered, *p);
size_t term_len = 0; size_t term_len = 0;