Actually looking at xterm it doesn't have a limit for this escape sequence, we can probably make tmux's a lot bigger so long as we reduce it back to 32 bytes after the sequence is done. Please try this instead:
diff --git a/input.c b/input.c index ee46c98..b6c27cb 100644 --- a/input.c +++ b/input.c @@ -55,6 +55,7 @@ void input_set_state(struct window_pane *, const struct input_transition *); /* Transition entry/exit handlers. */ void input_clear(struct input_ctx *); +void input_ground(struct input_ctx *); void input_enter_osc(struct input_ctx *); void input_exit_osc(struct input_ctx *); void input_enter_apc(struct input_ctx *); @@ -242,7 +243,7 @@ const struct input_transition input_state_utf8_one_table[]; /* ground state definition. */ const struct input_state input_state_ground = { "ground", - NULL, NULL, + input_ground, NULL, input_state_ground_table }; @@ -701,6 +702,12 @@ input_init(struct window_pane *wp) *ictx->param_buf = '\0'; ictx->param_len = 0; + ictx->input_space = INPUT_BUF_START; + ictx->input_buf = xmalloc(INPUT_BUF_START); + + *ictx->input_buf = '\0'; + ictx->input_len = 0; + ictx->state = &input_state_ground; ictx->flags = 0; @@ -711,8 +718,11 @@ input_init(struct window_pane *wp) void input_free(struct window_pane *wp) { - if (wp != NULL) - evbuffer_free(wp->ictx.since_ground); + if (wp == NULL) + return; + + free(wp->ictx.input_buf); + evbuffer_free(wp->ictx.since_ground); } /* Change input state. */ @@ -720,14 +730,9 @@ void input_set_state(struct window_pane *wp, const struct input_transition *itr) { struct input_ctx *ictx = &wp->ictx; - struct evbuffer *ground_evb = ictx->since_ground; if (ictx->state->exit != NULL) ictx->state->exit(ictx); - - if (itr->state == &input_state_ground) - evbuffer_drain(ground_evb, EVBUFFER_LENGTH(ground_evb)); - ictx->state = itr->state; if (ictx->state->enter != NULL) ictx->state->enter(ictx); @@ -882,6 +887,18 @@ input_clear(struct input_ctx *ictx) ictx->flags &= ~INPUT_DISCARD; } +/* Reset for ground state. */ +void +input_ground(struct input_ctx *ictx) +{ + evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground)); + + if (ictx->input_space > INPUT_BUF_START) { + ictx->input_space = INPUT_BUF_START; + ictx->input_buf = xrealloc(ictx->input_buf, 1, INPUT_BUF_START); + } +} + /* Output this character to the screen. */ int input_print(struct input_ctx *ictx) @@ -924,12 +941,20 @@ input_parameter(struct input_ctx *ictx) int input_input(struct input_ctx *ictx) { - if (ictx->input_len == (sizeof ictx->input_buf) - 1) - ictx->flags |= INPUT_DISCARD; - else { - ictx->input_buf[ictx->input_len++] = ictx->ch; - ictx->input_buf[ictx->input_len] = '\0'; + size_t available; + + available = ictx->input_space; + while (ictx->input_len + 1 >= available) { + available *= 2; + if (available > INPUT_BUF_LIMIT) { + ictx->flags |= INPUT_DISCARD; + return (0); + } + ictx->input_buf = xrealloc(ictx->input_buf, 1, available); + ictx->input_space = available; } + ictx->input_buf[ictx->input_len++] = ictx->ch; + ictx->input_buf[ictx->input_len] = '\0'; return (0); } @@ -1666,8 +1691,8 @@ input_enter_osc(struct input_ctx *ictx) void input_exit_osc(struct input_ctx *ictx) { - u_char *p = ictx->input_buf; - int option; + u_char *p = ictx->input_buf; + int option; if (ictx->flags & INPUT_DISCARD) return; diff --git a/tmux.h b/tmux.h index dacda66..b11d5a0 100644 --- a/tmux.h +++ b/tmux.h @@ -815,8 +815,11 @@ struct input_ctx { u_char param_buf[64]; size_t param_len; - u_char input_buf[256]; +#define INPUT_BUF_START 32 +#define INPUT_BUF_LIMIT 1048576 + u_char* input_buf; size_t input_len; + size_t input_space; int param_list[24]; /* -1 not present */ u_int param_list_len; On Tue, Apr 15, 2014 at 11:06:58AM -0700, Suraj Kurapati wrote: > On Tue, Apr 15, 2014 at 12:48 AM, Nicholas Marriott > <nicholas.marri...@gmail.com> wrote: > > I was going to bump the limit to 1K but that still seems a little short, > > try this please: > > > > diff --git a/input.c b/input.c > > index ee46c98..a8be6ad 100644 > > [...] > > That patch worked wonderfully, thank you! > > Here is my new observation on the maximum length of copyable text: > > bash$ printf "\ePtmux;\e\e]52;c;$(cat * | base64 -w0 | head -c32754)\a\e\\" > > Putting just 1 more byte in OSC52's base64 payload makes the copy fail: > > bash$ printf "\ePtmux;\e\e]52;c;$(cat * | base64 -w0 | head -c32755)\a\e\\" > > In total, this patch lets tmux pass 32772 bytes to the attached > terminal (that's 32754 bytes for OSC52's base64 payload plus 18 bytes > of overhead for the OSC52 and DCS escape sequences). That limit > correlates to the value of INPUT_LIMIT in tmux.h nicely. > > However, since the maximum length of an OSC 52 escape sequence is > 100,000 bytes[1] and the patched tmux's DCS escape sequence length > limit is 32772 bytes (as observed above), how would you recommend > sending a maximum-length OSC 52 escape sequence through tmux? > > Would splitting a maximum-length OSC 52 escape sequence into chunks > and sending them back-to-back in tmux's maximum-length DCS escape > sequences work? > > Thanks for your consideration. > > [1]: > http://git.chromium.org/gitweb/?p=chromiumos/platform/assets.git;a=blob;f=chromeapps/hterm/etc/osc52.vim;h=1cb6931d4f8ad028ca0a1c400389047e1b67228b;hb=HEAD#l21 ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/NeoTech _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users