зеркало из https://github.com/github/putty.git
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:
Родитель
a51dbf3f08
Коммит
2b5b843849
10
terminal.c
10
terminal.c
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче