diff --git a/input.c b/input.c index c89abc5f..b6eef671 100644 --- a/input.c +++ b/input.c @@ -93,7 +93,6 @@ struct input_ctx { size_t param_len; #define INPUT_BUF_START 32 -#define INPUT_BUF_LIMIT 1048576 u_char *input_buf; size_t input_len; size_t input_space; @@ -729,6 +728,9 @@ static const struct input_transition input_state_consume_st_table[] = { { -1, -1, NULL, NULL } }; +/* Maximum of bytes allowed to read in a single input. */ +static size_t input_buffer_size = INPUT_BUF_DEFAULT_SIZE; + /* Input table compare. */ static int input_table_compare(const void *key, const void *value) @@ -1193,7 +1195,7 @@ input_input(struct input_ctx *ictx) available = ictx->input_space; while (ictx->input_len + 1 >= available) { available *= 2; - if (available > INPUT_BUF_LIMIT) { + if (available > input_buffer_size) { ictx->flags |= INPUT_DISCARD; return (0); } @@ -3017,3 +3019,11 @@ input_reply_clipboard(struct bufferevent *bev, const char *buf, size_t len, bufferevent_write(bev, end, strlen(end)); free(out); } + +/* Set input buffer size. */ +void +input_set_buffer_size(size_t buffer_size) +{ + log_debug("%s: %lu -> %lu", __func__, input_buffer_size, buffer_size); + input_buffer_size = buffer_size; +} diff --git a/options-table.c b/options-table.c index 0711bceb..b327c1b4 100644 --- a/options-table.c +++ b/options-table.c @@ -348,6 +348,15 @@ const struct options_table_entry options_table[] = { "Empty does not write a history file." }, + { .name = "input-buffer-size", + .type = OPTIONS_TABLE_NUMBER, + .scope = OPTIONS_TABLE_SERVER, + .minimum = INPUT_BUF_DEFAULT_SIZE, + .maximum = UINT_MAX, + .default_num = INPUT_BUF_DEFAULT_SIZE, + .text = "Number of byte accpted in a single input before dropping." + }, + { .name = "menu-style", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW, diff --git a/options.c b/options.c index 854d4f45..74d34d88 100644 --- a/options.c +++ b/options.c @@ -1177,6 +1177,8 @@ options_push_changes(const char *name) RB_FOREACH(w, windows, &windows) layout_fix_panes(w, NULL); } + if (strcmp(name, "input-buffer-size") == 0) + input_set_buffer_size(options_get_number(global_options, name)); RB_FOREACH(s, sessions, &sessions) status_update_cache(s); diff --git a/tmux.1 b/tmux.1 index 3bdc2fba..3db4d647 100644 --- a/tmux.1 +++ b/tmux.1 @@ -4139,6 +4139,9 @@ option. If not empty, a file to which .Nm will write command prompt history on exit and load it from on start. +.It Ic input-buffer-size Ar bytes +Maximum of bytes allowed to read in escape and control sequences. +Once reached, the sequence will be discarded. .It Ic message-limit Ar number Set the number of error or information messages to save in the message log for each client. diff --git a/tmux.h b/tmux.h index ee1c2523..3d830d6a 100644 --- a/tmux.h +++ b/tmux.h @@ -2840,6 +2840,7 @@ void recalculate_sizes(void); void recalculate_sizes_now(int); /* input.c */ +#define INPUT_BUF_DEFAULT_SIZE 1048576 struct input_ctx *input_init(struct window_pane *, struct bufferevent *, struct colour_palette *); void input_free(struct input_ctx *); @@ -2851,6 +2852,7 @@ void input_parse_screen(struct input_ctx *, struct screen *, screen_write_init_ctx_cb, void *, u_char *, size_t); void input_reply_clipboard(struct bufferevent *, const char *, size_t, const char *); +void input_set_buffer_size(size_t); /* input-key.c */ void input_key_build(void);