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
1 changed files with 25 additions and 10 deletions

View File

@ -2445,11 +2445,6 @@ static struct config_schema g_config_behaviour[] =
.default_ = "off",
.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",
.comment = "Maximum number of lines stored in the backlog",
.type = CONFIG_ITEM_INTEGER,
@ -2463,7 +2458,7 @@ static struct config_schema g_config_behaviour[] =
{ .name = "backlog_helper_strip_formatting",
.comment = "Strip formatting from backlog helper input",
.type = CONFIG_ITEM_BOOLEAN,
.default_ = "on" },
.default_ = "off" },
{ .name = "reconnect_delay_growing",
.comment = "Growing factor for reconnect delay",
@ -2784,6 +2779,26 @@ struct attr_printer
#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
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)
tputs (attr, 1, printer);
else
// We shouldn't really do this but we need it to
// output formatting to the backlog
fputs (attr, self->stream);
// We shouldn't really do this but we need it to output formatting
// to the backlog helper--it should be SGR-only
attr_printer_filtered_puts (self->stream, attr);
}
static void
@ -3604,7 +3619,7 @@ explode_text (struct exploder *self, const char *text)
// Throw away any potentially harmful control characters first
struct str filtered = str_make ();
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);
size_t term_len = 0;