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.
This commit is contained in:
Avi Halachmi (:avih) 2019-10-16 12:55:53 +03:00 committed by Hiltjo Posthuma
parent 289c52b7aa
commit 2e54a21b5a

15
st.c
View file

@ -146,7 +146,8 @@ typedef struct {
/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */ /* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
typedef struct { typedef struct {
char type; /* ESC type ... */ 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 */ size_t len; /* raw string length */
char *args[STR_ARG_SIZ]; char *args[STR_ARG_SIZ];
int narg; /* nb of args */ int narg; /* nb of args */
@ -1948,7 +1949,10 @@ strdump(void)
void void
strreset(void) strreset(void)
{ {
memset(&strescseq, 0, sizeof(strescseq)); strescseq = (STREscape){
.buf = xrealloc(strescseq.buf, STR_BUF_SIZ),
.siz = STR_BUF_SIZ,
};
} }
void void
@ -2330,7 +2334,7 @@ tputc(Rune u)
if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q') if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
term.mode |= MODE_SIXEL; 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 * Here is a bug in terminals. If the user never sends
* some code to stop the str or esc command, then st * some code to stop the str or esc command, then st
@ -2344,7 +2348,10 @@ tputc(Rune u)
* term.esc = 0; * term.esc = 0;
* strhandle(); * 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); memmove(&strescseq.buf[strescseq.len], c, len);