mirror of
https://github.com/systemd/systemd
synced 2024-10-14 12:04:49 +00:00
Merge pull request #31514 from CodethinkLabs/ptyfwd_issues
ptyfwd/terminal-util: improve edge case handling
This commit is contained in:
commit
6aa14b283b
|
@ -1581,6 +1581,7 @@ typedef enum BackgroundColorState {
|
||||||
BACKGROUND_RED,
|
BACKGROUND_RED,
|
||||||
BACKGROUND_GREEN,
|
BACKGROUND_GREEN,
|
||||||
BACKGROUND_BLUE,
|
BACKGROUND_BLUE,
|
||||||
|
BACKGROUND_STRING_TERMINATOR,
|
||||||
} BackgroundColorState;
|
} BackgroundColorState;
|
||||||
|
|
||||||
typedef struct BackgroundColorContext {
|
typedef struct BackgroundColorContext {
|
||||||
|
@ -1672,7 +1673,9 @@ static int scan_background_color_response(
|
||||||
return 1; /* success! */
|
return 1; /* success! */
|
||||||
|
|
||||||
context->state = BACKGROUND_TEXT;
|
context->state = BACKGROUND_TEXT;
|
||||||
} else {
|
} else if (c == '\x1b')
|
||||||
|
context->state = context->blue_bits > 0 ? BACKGROUND_STRING_TERMINATOR : BACKGROUND_TEXT;
|
||||||
|
else {
|
||||||
int d = unhexchar(c);
|
int d = unhexchar(c);
|
||||||
if (d < 0 || context->blue_bits >= sizeof(context->blue)*8)
|
if (d < 0 || context->blue_bits >= sizeof(context->blue)*8)
|
||||||
context->state = BACKGROUND_TEXT;
|
context->state = BACKGROUND_TEXT;
|
||||||
|
@ -1682,10 +1685,18 @@ static int scan_background_color_response(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BACKGROUND_STRING_TERMINATOR:
|
||||||
|
if (c == '\\')
|
||||||
|
return 1; /* success! */
|
||||||
|
|
||||||
|
context->state = c == ']' ? BACKGROUND_ESCAPE : BACKGROUND_TEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset any colors we might have picked up */
|
/* Reset any colors we might have picked up */
|
||||||
if (context->state == BACKGROUND_TEXT) {
|
if (IN_SET(context->state, BACKGROUND_TEXT, BACKGROUND_ESCAPE)) {
|
||||||
/* reset color */
|
/* reset color */
|
||||||
context->red = context->green = context->blue = 0;
|
context->red = context->green = context->blue = 0;
|
||||||
context->red_bits = context->green_bits = context->blue_bits = 0;
|
context->red_bits = context->green_bits = context->blue_bits = 0;
|
||||||
|
@ -1744,6 +1755,10 @@ int get_default_background_color(double *ret_red, double *ret_green, double *ret
|
||||||
r = fd_wait_for_event(STDIN_FILENO, POLLIN, usec_sub_unsigned(end, n));
|
r = fd_wait_for_event(STDIN_FILENO, POLLIN, usec_sub_unsigned(end, n));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
if (r == 0) {
|
||||||
|
r = -EOPNOTSUPP;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t l;
|
ssize_t l;
|
||||||
l = read(STDIN_FILENO, buf, sizeof(buf) - buf_full);
|
l = read(STDIN_FILENO, buf, sizeof(buf) - buf_full);
|
||||||
|
|
|
@ -270,7 +270,9 @@ static int insert_newline_color_erase(PTYForward *f, size_t offset) {
|
||||||
_cleanup_free_ char *s = NULL;
|
_cleanup_free_ char *s = NULL;
|
||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
assert(f->background_color);
|
|
||||||
|
if (!f->background_color)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* When we see a newline (ASCII 10) then this sets the background color to the desired one, and erase the rest
|
/* When we see a newline (ASCII 10) then this sets the background color to the desired one, and erase the rest
|
||||||
* of the line with it */
|
* of the line with it */
|
||||||
|
@ -289,7 +291,9 @@ static int insert_carriage_return_color(PTYForward *f, size_t offset) {
|
||||||
_cleanup_free_ char *s = NULL;
|
_cleanup_free_ char *s = NULL;
|
||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
assert(f->background_color);
|
|
||||||
|
if (!f->background_color)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* When we see a carriage return (ASCII 13) this this sets only the background */
|
/* When we see a carriage return (ASCII 13) this this sets only the background */
|
||||||
|
|
||||||
|
@ -503,9 +507,15 @@ static int pty_forward_ansi_process(PTYForward *f, size_t offset) {
|
||||||
} else if (!strextend(&f->osc_sequence, CHAR_TO_STR(c)))
|
} else if (!strextend(&f->osc_sequence, CHAR_TO_STR(c)))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise, the OSC sequence is over */
|
/* Otherwise, the OSC sequence is over
|
||||||
|
*
|
||||||
|
* There are two allowed ways to end an OSC sequence:
|
||||||
|
* BEL '\x07'
|
||||||
|
* String Terminator (ST): <Esc>\ - "\x1b\x5c"
|
||||||
|
* since we cannot lookahead to see if the Esc is followed by a \
|
||||||
|
* we cut a corner here and assume it will be \. */
|
||||||
|
|
||||||
if (c == '\x07') {
|
if (c == '\x07' || c == '\x1b') {
|
||||||
r = insert_window_title_fix(f, i+1);
|
r = insert_window_title_fix(f, i+1);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
Loading…
Reference in a new issue