Support the REP escape sequence (CSI Pn b).

This causes the previous graphic character to be displayed another Pn
times (defaulting to 1, as usual). I just found out about it because
Ubuntu 18.04's ncurses expects it to be honoured.

According to all-escapes, REP is only supposed to be used when the
thing immediately preceding it in the terminal data stream _is_ a
printing character, and if not, then the behaviour is undefined. But
'undefined' is good enough for me to do the simple thing of just
remembering the last graphic character no matter whether anything else
has intervened since then.

To avoid DoS attacks using this escape sequence with a really huge Pn,
I clamp the value at the total size of the screen. There might be ways
to do that with more finesse (e.g. reduce it mod the width so that the
screen ends up looking the way it should even for huge parameters, or
reduce it even further if we notice the terminal isn't in wrapping
modes), but this will do for now.
This commit is contained in:
Simon Tatham 2018-05-18 14:17:06 +01:00
Родитель a51dbf3f08
Коммит 2b5b843849
2 изменённых файлов: 12 добавлений и 0 удалений

Просмотреть файл

@ -3379,6 +3379,7 @@ static void term_out(Terminal *term)
/* Only graphic characters get this far; /* Only graphic characters get this far;
* ctrls are stripped above */ * ctrls are stripped above */
term_display_graphic_char(term, c); term_display_graphic_char(term, c);
term->last_graphic_char = c;
break; break;
case OSC_MAYBE_ST: case OSC_MAYBE_ST:
@ -3644,6 +3645,15 @@ static void term_out(Terminal *term)
term->curs.y + def(term->esc_args[0], 1), 1); term->curs.y + def(term->esc_args[0], 1), 1);
seen_disp_event(term); seen_disp_event(term);
break; break;
case 'b': /* REP: repeat previous grap */
CLAMP(term->esc_args[0], term->rows * term->cols);
{
unsigned i;
for (i = 0; i < term->esc_args[0]; i++)
term_display_graphic_char(
term, term->last_graphic_char);
}
break;
case ANSI('c', '>'): /* DA: report xterm version */ case ANSI('c', '>'): /* DA: report xterm version */
compatibility(OTHER); compatibility(OTHER);
/* this reports xterm version 136 so that VIM can /* this reports xterm version 136 so that VIM can

Просмотреть файл

@ -238,6 +238,8 @@ struct terminal_tag {
struct unicode_data *ucsdata; struct unicode_data *ucsdata;
unsigned long last_graphic_char;
/* /*
* We maintain a full copy of a Conf here, not merely a pointer * We maintain a full copy of a Conf here, not merely a pointer
* to it. That way, when we're passed a new one for * to it. That way, when we're passed a new one for