Merge branch 'osc4-multi-parameter'

This commit is contained in:
Daniel Eklöf 2020-04-04 14:32:02 +02:00
commit 6d7c686a3c
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 51 additions and 50 deletions

View file

@ -46,6 +46,7 @@
* Restored cursor position in 'normal' screen when window was resized * Restored cursor position in 'normal' screen when window was resized
while in 'alt' screen. while in 'alt' screen.
* Hostname in OSC 7 URI not being validated. * Hostname in OSC 7 URI not being validated.
* OSC 4 with multiple `c;spec` pairs.
### Security ### Security

60
osc.c
View file

@ -430,29 +430,23 @@ osc_dispatch(struct terminal *term)
case 4: { case 4: {
/* Set color<idx> */ /* Set color<idx> */
/* First param - the color index */ string--;
assert(*string == ';');
for (const char *s_idx = strtok(string, ";"), *s_color = strtok(NULL, ";");
s_idx != NULL && s_color != NULL;
s_idx = strtok(NULL, ";"), s_color = strtok(NULL, ";"))
{
/* Parse <idx> parameter */
unsigned idx = 0; unsigned idx = 0;
for (; *string != '\0' && *string != ';'; string++) { for (; *s_idx != '\0'; s_idx++) {
char c = *string; char c = *s_idx;
idx *= 10; idx *= 10;
idx += c - '0'; idx += c - '0';
} }
if (idx >= 256)
break;
/* Next follows the color specification. For now, we only support rgb:x/y/z */
if (*string == '\0') {
/* No color specification */
break;
}
assert(*string == ';');
string++;
/* Client queried for current value */ /* Client queried for current value */
if (strlen(string) == 1 && string[0] == '?') { if (strlen(s_color) == 1 && s_color[0] == '?') {
uint32_t color = term->colors.table[idx]; uint32_t color = term->colors.table[idx];
uint8_t r = (color >> 16) & 0xff; uint8_t r = (color >> 16) & 0xff;
uint8_t g = (color >> 8) & 0xff; uint8_t g = (color >> 8) & 0xff;
@ -462,15 +456,22 @@ osc_dispatch(struct terminal *term)
snprintf(reply, sizeof(reply), "\033]4;%u;rgb:%02x/%02x/%02x\033\\", snprintf(reply, sizeof(reply), "\033]4;%u;rgb:%02x/%02x/%02x\033\\",
idx, r, g, b); idx, r, g, b);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, strlen(reply));
break;
} }
else {
uint32_t color; uint32_t color;
if (string[0] == '#' ? !parse_legacy_color(string, &color) : !parse_rgb(string, &color)) bool color_is_valid = s_color[0] == '#'
break; ? parse_legacy_color(s_color, &color)
: parse_rgb(s_color, &color);
if (!color_is_valid)
continue;
LOG_DBG("change color definition for #%u to %06x", idx, color); LOG_DBG("change color definition for #%u to %06x", idx, color);
term->colors.table[idx] = color; term->colors.table[idx] = color;
}
}
render_refresh(term); render_refresh(term);
break; break;
} }
@ -558,18 +559,16 @@ osc_dispatch(struct terminal *term)
LOG_DBG("resetting all colors"); LOG_DBG("resetting all colors");
for (size_t i = 0; i < 256; i++) for (size_t i = 0; i < 256; i++)
term->colors.table[i] = term->colors.default_table[i]; term->colors.table[i] = term->colors.default_table[i];
} else {
unsigned idx = 0;
for (; *string != '\0'; string++) {
char c = *string;
if (c == ';') {
LOG_DBG("resetting color #%u", idx);
term->colors.table[idx] = term->colors.default_table[idx];
idx = 0;
continue;
} }
else {
for (const char *s_idx = strtok(string, ";");
s_idx != NULL;
s_idx = strtok(NULL, ";"))
{
unsigned idx = 0;
for (; *s_idx != '\0'; s_idx++) {
char c = *s_idx;
idx *= 10; idx *= 10;
idx += c - '0'; idx += c - '0';
} }
@ -577,6 +576,7 @@ osc_dispatch(struct terminal *term)
LOG_DBG("resetting color #%u", idx); LOG_DBG("resetting color #%u", idx);
term->colors.table[idx] = term->colors.default_table[idx]; term->colors.table[idx] = term->colors.default_table[idx];
} }
}
render_refresh(term); render_refresh(term);
break; break;