diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-04-27 14:30:25 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-04-27 14:30:25 +0200 |
commit | 360d54234f76a3cc478dcfcc52935dcfcbaead34 (patch) | |
tree | 83cd07c16940fc6a32612607398c6d709e38c122 | |
parent | fd051d463a920541baf17b8a087bc0ce0173e71c (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.c | 503 |
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; } |