OSC 52 - copy to clipboard: don't limit to 382 bytes
[st.git] / st.c
diff --git a/st.c b/st.c
index 0c1acd4..3e48410 100644 (file)
--- a/st.c
+++ b/st.c
@@ -146,7 +146,8 @@ typedef struct {
 /* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
 typedef struct {
        char type;             /* ESC type ... */
-       char buf[STR_BUF_SIZ]; /* raw string */
+       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 */
@@ -1948,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
@@ -2330,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)) {
+               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
@@ -2344,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);