X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=3e4841079a90ce76e83a9cbe361b7a46e71ff9a2;hb=895e5b50a8cc835c19a45e1e328eb4dc78f5fd0c;hp=0628707eae4bc351c483caf7477782d8273203b4;hpb=041912a791e8c2f4d5d2415b16210d29d7e701c5;p=st.git diff --git a/st.c b/st.c index 0628707..3e48410 100644 --- a/st.c +++ b/st.c @@ -38,14 +38,10 @@ /* macros */ #define IS_SET(flag) ((term.mode & (flag)) != 0) -#define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) -#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL) - -/* constants */ -#define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: ] [;]] []] */ typedef struct { char buf[ESC_BUF_SIZ]; /* raw string */ - int len; /* raw string length */ + size_t len; /* raw string length */ char priv; int arg[ESC_ARG_SIZ]; int narg; /* nb of args */ @@ -150,8 +146,9 @@ typedef struct { /* ESC type [[ [] [;]] ] ESC '\' */ typedef struct { char type; /* ESC type ... */ - char buf[STR_BUF_SIZ]; /* raw string */ - int len; /* raw string length */ + char *buf; /* allocated raw string */ + size_t siz; /* allocation size */ + size_t len; /* raw string length */ char *args[STR_ARG_SIZ]; int narg; /* nb of args */ } STREscape; @@ -214,7 +211,6 @@ static void selsnap(int *, int *, int); static size_t utf8decode(const char *, Rune *, size_t); static Rune utf8decodebyte(char, size_t *); static char utf8encodebyte(Rune, size_t); -static char *utf8strchr(char *, Rune); static size_t utf8validate(Rune *, size_t); static char *base64dec(const char *); @@ -341,23 +337,6 @@ utf8encodebyte(Rune u, size_t i) return utfbyte[i] | (u & ~utfmask[i]); } -char * -utf8strchr(char *s, Rune u) -{ - Rune r; - size_t i, j, len; - - len = strlen(s); - for (i = 0, j = 0; i < len; i += j) { - if (!(j = utf8decode(&s[i], &r, len - i))) - break; - if (r == u) - return &(s[i]); - } - - return NULL; -} - size_t utf8validate(Rune *u, size_t i) { @@ -388,7 +367,7 @@ char base64dec_getc(const char **src) { while (**src && !isprint(**src)) (*src)++; - return *((*src)++); + return **src ? *((*src)++) : '='; /* emulate padding if string ends */ } char * @@ -406,6 +385,10 @@ base64dec(const char *src) int c = base64_digits[(unsigned char) base64dec_getc(&src)]; int d = base64_digits[(unsigned char) base64dec_getc(&src)]; + /* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */ + if (a == -1 || b == -1) + break; + *dst++ = (a << 2) | ((b & 0x30) >> 4); if (c == -1) break; @@ -480,7 +463,7 @@ selextend(int col, int row, int type, int done) selnormalize(); sel.type = type; - if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type) + if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY) tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); sel.mode = done ? SEL_IDLE : SEL_READY; @@ -735,8 +718,10 @@ sigchld(int a) if (pid != p) return; - if (!WIFEXITED(stat) || WEXITSTATUS(stat)) - die("child finished with error '%d'\n", stat); + if (WIFEXITED(stat) && WEXITSTATUS(stat)) + die("child exited with status %d\n", WEXITSTATUS(stat)); + else if (WIFSIGNALED(stat)) + die("child terminated due to signal %d\n", WTERMSIG(stat)); exit(0); } @@ -806,9 +791,17 @@ ttynew(char *line, char *cmd, char *out, char **args) die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); close(s); close(m); +#ifdef __OpenBSD__ + if (pledge("stdio getpw proc exec", NULL) == -1) + die("pledge\n"); +#endif execsh(cmd, args); break; default: +#ifdef __OpenBSD__ + if (pledge("stdio rpath tty proc", NULL) == -1) + die("pledge\n"); +#endif close(s); cmdfd = m; signal(SIGCHLD, sigchld); @@ -1448,7 +1441,8 @@ tsetattr(int *attr, int l) } else { fprintf(stderr, "erresc(default): gfx attr %d unknown\n", - attr[i]), csidump(); + attr[i]); + csidump(); } break; } @@ -1568,6 +1562,7 @@ tsetmode(int priv, int set, int *args, int narg) case 1015: /* urxvt mangled mouse mode; incompatible and can be mistaken for other control codes. */ + break; default: fprintf(stderr, "erresc: unknown private set/reset mode %d\n", @@ -1809,7 +1804,7 @@ csihandle(void) void csidump(void) { - int i; + size_t i; uint c; fprintf(stderr, "ESC["); @@ -1839,7 +1834,7 @@ csireset(void) void strhandle(void) { - char *p = NULL; + char *p = NULL, *dec; int j, narg, par; term.esc &= ~(ESC_STR_END|ESC_STR); @@ -1857,8 +1852,6 @@ strhandle(void) return; case 52: if (narg > 2) { - char *dec; - dec = base64dec(strescseq.args[2]); if (dec) { xsetsel(dec); @@ -1876,7 +1869,10 @@ strhandle(void) case 104: /* color reset, here p = NULL */ j = (narg > 1) ? atoi(strescseq.args[1]) : -1; if (xsetcolorname(j, p)) { - fprintf(stderr, "erresc: invalid color %s\n", p); + if (par == 104 && narg <= 1) + return; /* color reset without parameter */ + fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", + j, p ? p : "(null)"); } else { /* * TODO if defaultbg color is changed, borders @@ -1926,7 +1922,7 @@ strparse(void) void strdump(void) { - int i; + size_t i; uint c; fprintf(stderr, "ESC%c", strescseq.type); @@ -1953,7 +1949,10 @@ strdump(void) void strreset(void) { - memset(&strescseq, 0, sizeof(strescseq)); + strescseq = (STREscape){ + .buf = xrealloc(strescseq.buf, STR_BUF_SIZ), + .siz = STR_BUF_SIZ, + }; } void @@ -1973,28 +1972,6 @@ tprinter(char *s, size_t len) } } -void -iso14755(const Arg *arg) -{ - FILE *p; - char *us, *e, codepoint[9], uc[UTF_SIZ]; - unsigned long utf32; - - if (!(p = popen(ISO14755CMD, "r"))) - return; - - us = fgets(codepoint, sizeof(codepoint), p); - pclose(p); - - if (!us || *us == '\0' || *us == '-' || strlen(us) > 7) - return; - if ((utf32 = strtoul(us, &e, 16)) == ULONG_MAX || - (*e != '\n' && *e != '\0')) - return; - - ttywrite(uc, utf8encode(utf32, uc), 1); -} - void toggleprinter(const Arg *arg) { @@ -2279,7 +2256,7 @@ eschandle(uchar ascii) case 'Z': /* DECID -- Identify Terminal */ ttywrite(vtiden, strlen(vtiden), 0); break; - case 'c': /* RIS -- Reset to inital state */ + case 'c': /* RIS -- Reset to initial state */ treset(); resettitle(); xloadcols(); @@ -2350,7 +2327,6 @@ tputc(Rune u) goto check_control_code; } - if (IS_SET(MODE_SIXEL)) { /* TODO: implement sixel mode */ return; @@ -2358,7 +2334,7 @@ tputc(Rune u) if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q') term.mode |= MODE_SIXEL; - if (strescseq.len+len >= sizeof(strescseq.buf)-1) { + if (strescseq.len+len >= strescseq.siz) { /* * Here is a bug in terminals. If the user never sends * some code to stop the str or esc command, then st @@ -2372,7 +2348,10 @@ tputc(Rune u) * term.esc = 0; * strhandle(); */ - return; + if (strescseq.siz > (SIZE_MAX - UTF_SIZ) / 2) + return; + strescseq.siz *= 2; + strescseq.buf = xrealloc(strescseq.buf, strescseq.siz); } memmove(&strescseq.buf[strescseq.len], c, len); @@ -2609,6 +2588,7 @@ draw(void) term.ocx, term.ocy, term.line[term.ocy][term.ocx]); term.ocx = cx, term.ocy = term.c.y; xfinishdraw(); + xximspot(term.ocx, term.ocy); } void