[hackers] [st] OSC 52 - copy to clipboard: don't limit to 382 bytes || Avi Halachmi (:avih)

From: <git_AT_suckless.org>
Date: Sun, 10 Nov 2019 22:46:51 +0100 (CET)

commit 2e54a21b5ae249a6bcedab9db611ea86037a018b
Author: Avi Halachmi (:avih) <avihpit_AT_yahoo.com>
AuthorDate: Wed Oct 16 12:55:53 2019 +0300
Commit: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
CommitDate: Sun Nov 10 22:45:54 2019 +0100

    OSC 52 - copy to clipboard: don't limit to 382 bytes
    
    Strings which an application sends to the terminal in OSC, DCS, etc
    are typically small (title, colors, etc) but one exception is OSC 52
    which copies text to the clipboard, and is used for instance by tmux.
    
    Previously st cropped these strings at 512 bytes, which for OSC 52
    limited the copied text to 382 bytes (remaining buffer space before
    base64). This made it less useful than it can be.
    
    Now it's a dynamic growing buffer. It remains allocated after use,
    resets to 512 when a new string starts, or leaked on exit.
    
    Resetting/deallocating the buffer right after use (at strhandle) is
    possible with some more code, however, it doesn't always end up used,
    and to cover those cases too will require even more code, so resetting
    only on new string is good enough for now.

diff --git a/st.c b/st.c
index 0c1acd4..3e48410 100644
--- a/st.c
+++ b/st.c
_AT_@ -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 */
_AT_@ -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
_AT_@ -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
_AT_@ -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);
Received on Sun Nov 10 2019 - 22:46:51 CET

This archive was generated by hypermail 2.3.0 : Sun Nov 10 2019 - 22:48:25 CET