summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2025-04-27 14:30:25 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2025-04-27 14:30:25 +0200
commit360d54234f76a3cc478dcfcc52935dcfcbaead34 (patch)
tree83cd07c16940fc6a32612607398c6d709e38c122
parentfd051d463a920541baf17b8a087bc0ce0173e71c (diff)
kd: Discard unsupported ansi sequences
"modern" software seem to like spitting sequences without checking for their support in terminfo, leading to various spurious output, see e.g. https://github.com/takluyver/bash_kernel/issues/107 Just drop anything we don't support, to avoid getting hit.
-rw-r--r--i386/i386at/kd.c503
1 files changed, 280 insertions, 223 deletions
diff --git a/i386/i386at/kd.c b/i386/i386at/kd.c
index 7e13fdf4..3774fe79 100644
--- a/i386/i386at/kd.c
+++ b/i386/i386at/kd.c
@@ -1475,6 +1475,16 @@ kd_parserest(u_char *cp)
{
int number[16], npar = 0, i;
csrpos_t newpos;
+ boolean_t question = FALSE;
+ boolean_t angle = FALSE;
+
+ if (*cp == '?') {
+ question = TRUE;
+ cp++;
+ } else if (*cp == '<') {
+ angle = TRUE;
+ cp++;
+ }
for(i=0;i<=15;i++)
number[i] = MACH_ATOI_DEFAULT;
@@ -1483,253 +1493,300 @@ kd_parserest(u_char *cp)
cp += mach_atoi(cp, &number[npar]);
} while (*cp == ';' && ++npar <= 15 && cp++);
- switch(*cp) {
- case 'm':
- for (i=0;i<=npar;i++)
- switch(number[i]) {
+ if (question) {
+ /* \e[?... */
+ switch(*cp) {
+ case '\0':
+ break; /* not enough yet */
+ default:
+ if ((*cp >= 'a' && *cp <= 'z') || (*cp >= 'A' && *cp <= 'Z'))
+ {
+ /* Unsupported sequence, just silently drop */
+ }
+ else
+ {
+ /* Odd sequence, print it */
+ kd_putc(*cp); /* show inv character */
+ }
+ esc_spt = esc_seq; /* inv entry, reset */
+ break;
+ }
+ } else if (angle) {
+ /* \e[<... */
+ switch(*cp) {
+ case '\0':
+ break; /* not enough yet */
+ default:
+ if ((*cp >= 'a' && *cp <= 'z') || (*cp >= 'A' && *cp <= 'Z'))
+ {
+ /* Unsupported sequence, just silently drop */
+ }
+ else
+ {
+ /* Odd sequence, print it */
+ kd_putc(*cp); /* show inv character */
+ }
+ esc_spt = esc_seq; /* inv entry, reset */
+ break;
+ }
+ } else {
+ /* \e[... */
+ switch(*cp) {
+ case 'm':
+ for (i=0;i<=npar;i++)
+ switch(number[i]) {
+ case MACH_ATOI_DEFAULT:
+ case 0:
+ kd_attrflags = 0;
+ kd_color = KA_NORMAL;
+ break;
+ case 1:
+ kd_attrflags |= KAX_BOLD;
+ kd_attrflags &= ~KAX_DIM;
+ break;
+ case 2:
+ kd_attrflags |= KAX_DIM;
+ kd_attrflags &= ~KAX_BOLD;
+ break;
+ case 4:
+ kd_attrflags |= KAX_UNDERLINE;
+ break;
+ case 5:
+ kd_attrflags |= KAX_BLINK;
+ break;
+ case 7:
+ kd_attrflags |= KAX_REVERSE;
+ break;
+ case 8:
+ kd_attrflags |= KAX_INVISIBLE;
+ break;
+ case 21:
+ case 22:
+ kd_attrflags &= ~(KAX_BOLD | KAX_DIM);
+ break;
+ case 24:
+ kd_attrflags &= ~KAX_UNDERLINE;
+ break;
+ case 25:
+ kd_attrflags &= ~KAX_BLINK;
+ break;
+ case 27:
+ kd_attrflags &= ~KAX_REVERSE;
+ break;
+ case 38:
+ kd_attrflags |= KAX_UNDERLINE;
+ kd_color = (kd_color & 0xf0) | (KA_NORMAL & 0x0f);
+ break;
+ case 39:
+ kd_attrflags &= ~KAX_UNDERLINE;
+ kd_color = (kd_color & 0xf0) | (KA_NORMAL & 0x0f);
+ break;
+ default:
+ if (number[i] >= 30 && number[i] <= 37) {
+ /* foreground color */
+ kd_color = (kd_color & 0xf0) | color_table[(number[i] - 30)];
+ } else if (number[i] >= 40 && number[i] <= 47) {
+ /* background color */
+ kd_color = (kd_color & 0x0f) | (color_table[(number[i] - 40)] << 4);
+ }
+ break;
+ }
+ kd_update_kd_attr();
+ esc_spt = esc_seq;
+ break;
+ case '@':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_insch(1);
+ else
+ kd_insch(number[0]);
+ esc_spt = esc_seq;
+ break;
+ case 'A':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_up();
+ else
+ while (number[0]--)
+ kd_up();
+ esc_spt = esc_seq;
+ break;
+ case 'B':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_down();
+ else
+ while (number[0]--)
+ kd_down();
+ esc_spt = esc_seq;
+ break;
+ case 'C':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_right();
+ else
+ while (number[0]--)
+ kd_right();
+ esc_spt = esc_seq;
+ break;
+ case 'D':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_left();
+ else
+ while (number[0]--)
+ kd_left();
+ esc_spt = esc_seq;
+ break;
+ case 'E':
+ kd_cr();
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_down();
+ else
+ while (number[0]--)
+ kd_down();
+ esc_spt = esc_seq;
+ break;
+ case 'F':
+ kd_cr();
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_up();
+ else
+ while (number[0]--)
+ kd_up();
+ esc_spt = esc_seq;
+ break;
+ case 'G':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ number[0] = 0;
+ else
+ if (number[0] > 0)
+ --number[0]; /* because number[0] is from 1 */
+ kd_setpos(BEG_OF_LINE(kd_curpos) + number[0] * ONE_SPACE);
+ esc_spt = esc_seq;
+ break;
+ case 'f':
+ case 'H':
+ if (number[0] == MACH_ATOI_DEFAULT && number[1] == MACH_ATOI_DEFAULT)
+ {
+ kd_home();
+ esc_spt = esc_seq;
+ break;
+ }
+ if (number[0] == MACH_ATOI_DEFAULT)
+ number[0] = 0;
+ else if (number[0] > 0)
+ --number[0]; /* numbered from 1 */
+ newpos = (number[0] * ONE_LINE); /* setup row */
+ if (number[1] == MACH_ATOI_DEFAULT)
+ number[1] = 0;
+ else if (number[1] > 0)
+ number[1]--;
+ newpos += (number[1] * ONE_SPACE); /* setup column */
+ if (newpos < 0)
+ newpos = 0; /* upper left */
+ if (newpos > ONE_PAGE)
+ newpos = (ONE_PAGE - ONE_SPACE); /* lower right */
+ kd_setpos(newpos);
+ esc_spt = esc_seq;
+ break; /* done or not ready */
+ case 'J':
+ switch(number[0]) {
case MACH_ATOI_DEFAULT:
case 0:
- kd_attrflags = 0;
- kd_color = KA_NORMAL;
+ kd_cltobcur(); /* clears from current
+ pos to bottom.
+ */
break;
case 1:
- kd_attrflags |= KAX_BOLD;
- kd_attrflags &= ~KAX_DIM;
+ kd_cltopcur(); /* clears from top to
+ current pos.
+ */
break;
case 2:
- kd_attrflags |= KAX_DIM;
- kd_attrflags &= ~KAX_BOLD;
- break;
- case 4:
- kd_attrflags |= KAX_UNDERLINE;
+ kd_cls();
break;
- case 5:
- kd_attrflags |= KAX_BLINK;
- break;
- case 7:
- kd_attrflags |= KAX_REVERSE;
- break;
- case 8:
- kd_attrflags |= KAX_INVISIBLE;
- break;
- case 21:
- case 22:
- kd_attrflags &= ~(KAX_BOLD | KAX_DIM);
- break;
- case 24:
- kd_attrflags &= ~KAX_UNDERLINE;
- break;
- case 25:
- kd_attrflags &= ~KAX_BLINK;
+ default:
break;
- case 27:
- kd_attrflags &= ~KAX_REVERSE;
+ }
+ esc_spt = esc_seq; /* reset it */
+ break;
+ case 'K':
+ switch(number[0]) {
+ case MACH_ATOI_DEFAULT:
+ case 0:
+ kd_cltoecur(); /* clears from current
+ pos to eoln.
+ */
break;
- case 38:
- kd_attrflags |= KAX_UNDERLINE;
- kd_color = (kd_color & 0xf0) | (KA_NORMAL & 0x0f);
+ case 1:
+ kd_clfrbcur(); /* clears from begin
+ of line to current
+ pos.
+ */
break;
- case 39:
- kd_attrflags &= ~KAX_UNDERLINE;
- kd_color = (kd_color & 0xf0) | (KA_NORMAL & 0x0f);
+ case 2:
+ kd_eraseln(); /* clear entire line */
break;
default:
- if (number[i] >= 30 && number[i] <= 37) {
- /* foreground color */
- kd_color = (kd_color & 0xf0) | color_table[(number[i] - 30)];
- } else if (number[i] >= 40 && number[i] <= 47) {
- /* background color */
- kd_color = (kd_color & 0x0f) | (color_table[(number[i] - 40)] << 4);
- }
- break;
+ break;
}
- kd_update_kd_attr();
- esc_spt = esc_seq;
- break;
- case '@':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_insch(1);
- else
- kd_insch(number[0]);
- esc_spt = esc_seq;
- break;
- case 'A':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_up();
- else
- while (number[0]--)
- kd_up();
- esc_spt = esc_seq;
- break;
- case 'B':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_down();
- else
- while (number[0]--)
- kd_down();
- esc_spt = esc_seq;
- break;
- case 'C':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_right();
- else
- while (number[0]--)
- kd_right();
- esc_spt = esc_seq;
- break;
- case 'D':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_left();
- else
- while (number[0]--)
- kd_left();
- esc_spt = esc_seq;
- break;
- case 'E':
- kd_cr();
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_down();
- else
- while (number[0]--)
- kd_down();
- esc_spt = esc_seq;
- break;
- case 'F':
- kd_cr();
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_up();
- else
- while (number[0]--)
- kd_up();
- esc_spt = esc_seq;
- break;
- case 'G':
- if (number[0] == MACH_ATOI_DEFAULT)
- number[0] = 0;
- else
- if (number[0] > 0)
- --number[0]; /* because number[0] is from 1 */
- kd_setpos(BEG_OF_LINE(kd_curpos) + number[0] * ONE_SPACE);
- esc_spt = esc_seq;
- break;
- case 'f':
- case 'H':
- if (number[0] == MACH_ATOI_DEFAULT && number[1] == MACH_ATOI_DEFAULT)
- {
- kd_home();
esc_spt = esc_seq;
break;
- }
- if (number[0] == MACH_ATOI_DEFAULT)
- number[0] = 0;
- else if (number[0] > 0)
- --number[0]; /* numbered from 1 */
- newpos = (number[0] * ONE_LINE); /* setup row */
- if (number[1] == MACH_ATOI_DEFAULT)
- number[1] = 0;
- else if (number[1] > 0)
- number[1]--;
- newpos += (number[1] * ONE_SPACE); /* setup column */
- if (newpos < 0)
- newpos = 0; /* upper left */
- if (newpos > ONE_PAGE)
- newpos = (ONE_PAGE - ONE_SPACE); /* lower right */
- kd_setpos(newpos);
- esc_spt = esc_seq;
- break; /* done or not ready */
- case 'J':
- switch(number[0]) {
- case MACH_ATOI_DEFAULT:
- case 0:
- kd_cltobcur(); /* clears from current
- pos to bottom.
- */
- break;
- case 1:
- kd_cltopcur(); /* clears from top to
- current pos.
- */
+ case 'L':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_insln(1);
+ else
+ kd_insln(number[0]);
+ esc_spt = esc_seq;
break;
- case 2:
- kd_cls();
+ case 'M':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_delln(1);
+ else
+ kd_delln(number[0]);
+ esc_spt = esc_seq;
break;
- default:
+ case 'P':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_delch(1);
+ else
+ kd_delch(number[0]);
+ esc_spt = esc_seq;
break;
- }
- esc_spt = esc_seq; /* reset it */
- break;
- case 'K':
- switch(number[0]) {
- case MACH_ATOI_DEFAULT:
- case 0:
- kd_cltoecur(); /* clears from current
- pos to eoln.
- */
+ case 'S':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_scrollup();
+ else
+ while (number[0]--)
+ kd_scrollup();
+ esc_spt = esc_seq;
break;
- case 1:
- kd_clfrbcur(); /* clears from begin
- of line to current
- pos.
- */
+ case 'T':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_scrolldn();
+ else
+ while (number[0]--)
+ kd_scrolldn();
+ esc_spt = esc_seq;
break;
- case 2:
- kd_eraseln(); /* clear entire line */
+ case 'X':
+ if (number[0] == MACH_ATOI_DEFAULT)
+ kd_erase(1);
+ else
+ kd_erase(number[0]);
+ esc_spt = esc_seq;
break;
+ case '\0':
+ break; /* not enough yet */
default:
+ if ((*cp >= 'a' && *cp <= 'z') || (*cp >= 'A' && *cp <= 'Z'))
+ {
+ /* Unsupported sequence, just silently drop */
+ }
+ else
+ {
+ /* Odd sequence, print it */
+ kd_putc(*cp); /* show inv character */
+ }
+ esc_spt = esc_seq; /* inv entry, reset */
break;
}
- esc_spt = esc_seq;
- break;
- case 'L':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_insln(1);
- else
- kd_insln(number[0]);
- esc_spt = esc_seq;
- break;
- case 'M':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_delln(1);
- else
- kd_delln(number[0]);
- esc_spt = esc_seq;
- break;
- case 'P':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_delch(1);
- else
- kd_delch(number[0]);
- esc_spt = esc_seq;
- break;
- case 'S':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_scrollup();
- else
- while (number[0]--)
- kd_scrollup();
- esc_spt = esc_seq;
- break;
- case 'T':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_scrolldn();
- else
- while (number[0]--)
- kd_scrolldn();
- esc_spt = esc_seq;
- break;
- case 'X':
- if (number[0] == MACH_ATOI_DEFAULT)
- kd_erase(1);
- else
- kd_erase(number[0]);
- esc_spt = esc_seq;
- break;
- case '\0':
- break; /* not enough yet */
- default:
- kd_putc(*cp); /* show inv character */
- esc_spt = esc_seq; /* inv entry, reset */
- break;
}
return;
}