]> Sergey Matveev's repositories - st.git/blobdiff - st.c
avoid potential UB when using isprint()
[st.git] / st.c
diff --git a/st.c b/st.c
index a9338e1a5771762cd0e53fb2f215dccd3378737e..1307fdf4ab3afee8d16af827b1a04a99152cf1ec 100644 (file)
--- a/st.c
+++ b/st.c
@@ -367,7 +367,7 @@ static const char base64_digits[] = {
 char
 base64dec_getc(const char **src)
 {
-       while (**src && !isprint(**src))
+       while (**src && !isprint((unsigned char)**src))
                (*src)++;
        return **src ? *((*src)++) : '=';  /* emulate padding if string ends */
 }
@@ -1842,6 +1842,42 @@ csireset(void)
        memset(&csiescseq, 0, sizeof(csiescseq));
 }
 
+void
+osc4_color_response(int num)
+{
+       int n;
+       char buf[32];
+       unsigned char r, g, b;
+
+       if (xgetcolor(num, &r, &g, &b)) {
+               fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num);
+               return;
+       }
+
+       n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
+                    num, r, r, g, g, b, b);
+
+       ttywrite(buf, n, 1);
+}
+
+void
+osc_color_response(int index, int num)
+{
+       int n;
+       char buf[32];
+       unsigned char r, g, b;
+
+       if (xgetcolor(index, &r, &g, &b)) {
+               fprintf(stderr, "erresc: failed to fetch osc color %d\n", index);
+               return;
+       }
+
+       n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
+                    num, r, r, g, g, b, b);
+
+       ttywrite(buf, n, 1);
+}
+
 void
 strhandle(void)
 {
@@ -1880,14 +1916,56 @@ strhandle(void)
                                }
                        }
                        return;
+               case 10:
+                       if (narg < 2)
+                               break;
+
+                       p = strescseq.args[1];
+
+                       if (!strcmp(p, "?"))
+                               osc_color_response(defaultfg, 10);
+                       else if (xsetcolorname(defaultfg, p))
+                               fprintf(stderr, "erresc: invalid foreground color: %s\n", p);
+                       else
+                               tfulldirt();
+                       return;
+               case 11:
+                       if (narg < 2)
+                               break;
+
+                       p = strescseq.args[1];
+
+                       if (!strcmp(p, "?"))
+                               osc_color_response(defaultbg, 11);
+                       else if (xsetcolorname(defaultbg, p))
+                               fprintf(stderr, "erresc: invalid background color: %s\n", p);
+                       else
+                               tfulldirt();
+                       return;
+               case 12:
+                       if (narg < 2)
+                               break;
+
+                       p = strescseq.args[1];
+
+                       if (!strcmp(p, "?"))
+                               osc_color_response(defaultcs, 12);
+                       else if (xsetcolorname(defaultcs, p))
+                               fprintf(stderr, "erresc: invalid cursor color: %s\n", p);
+                       else
+                               tfulldirt();
+                       return;
                case 4: /* color set */
                        if (narg < 3)
                                break;
                        p = strescseq.args[2];
                        /* FALLTHROUGH */
-               case 104: /* color reset, here p = NULL */
+               case 104: /* color reset */
                        j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
-                       if (xsetcolorname(j, p)) {
+
+                       if (p && !strcmp(p, "?"))
+                               osc4_color_response(j);
+                       else if (xsetcolorname(j, p)) {
                                if (par == 104 && narg <= 1)
                                        return; /* color reset without parameter */
                                fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
@@ -1897,7 +1975,7 @@ strhandle(void)
                                 * TODO if defaultbg color is changed, borders
                                 * are dirty
                                 */
-                               redraw();
+                               tfulldirt();
                        }
                        return;
                }
@@ -2429,6 +2507,10 @@ check_control_code:
        if (width == 2) {
                gp->mode |= ATTR_WIDE;
                if (term.c.x+1 < term.col) {
+                       if (gp[1].mode == ATTR_WIDE && term.c.x+2 < term.col) {
+                               gp[2].u = ' ';
+                               gp[2].mode &= ~ATTR_WDUMMY;
+                       }
                        gp[1].u = '\0';
                        gp[1].mode = ATTR_WDUMMY;
                }