diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-15 12:40:44 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-15 12:40:44 +0300 |
| commit | 7b31d6a05357953c035e2ab05ec117ef748f7798 (patch) | |
| tree | 26fea99ff05dce6f076b74e35a19c14a53762653 | |
| parent | ca69844a243a6e335b0ddafad057f35e89e0a576 (diff) | |
Reject a scrollback above TERM_SCROLLBACK_MAX
term_new() silently cut a scrollback above 1000000 lines to 1000000.
The limit now has a name in term.h, and term_new() returns NULL above
it, as it does for the other invalid options.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| -rw-r--r-- | include/term/term.h | 5 | ||||
| -rw-r--r-- | src/screen.c | 9 | ||||
| -rw-r--r-- | tests/api_args_test.c | 10 |
3 files changed, 18 insertions, 6 deletions
diff --git a/include/term/term.h b/include/term/term.h index 380dfd3..c69e88e 100644 --- a/include/term/term.h +++ b/include/term/term.h @@ -40,6 +40,8 @@ struct term_snapshot; #define TERM_MAX_COLS 65535 /* The history limit when term_options.scrollback is 0. */ #define TERM_SCROLLBACK_DEFAULT 10000 +/* The largest term_options.scrollback. */ +#define TERM_SCROLLBACK_MAX 1000000 /* * The version of this header. A host compares TERM_VERSION_CODE with @@ -153,7 +155,8 @@ struct term_callbacks { /* * Options for term_new(). An all-zero value is valid. A size component of 0 * selects 80 columns or 24 rows. A negative component, or columns above - * TERM_MAX_COLS, makes term_new() fail. A negative scrollback fails too. + * TERM_MAX_COLS, makes term_new() fail. A scrollback below 0 or above + * TERM_SCROLLBACK_MAX fails too. * cursor_style must be a value of enum term_cursor_style. */ struct term_options { diff --git a/src/screen.c b/src/screen.c index b99948d..ab6989a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -808,12 +808,10 @@ void term_screen_set_alternate(struct term *t, bool enabled) } } -/* The caller has checked that requested is not negative. */ +/* The caller has checked that requested is in [0, TERM_SCROLLBACK_MAX]. */ static int scrollback_lines(int requested) { - if (requested == 0) - return TERM_SCROLLBACK_DEFAULT; - return requested > 1000000 ? 1000000 : requested; + return requested == 0 ? TERM_SCROLLBACK_DEFAULT : requested; } static atomic_int tables_state; @@ -862,7 +860,8 @@ struct term *term_new(const struct term_options *opt) return NULL; if (opt->size.x < 0 || opt->size.y < 0 || opt->size.x > TERM_MAX_COLS) return NULL; - if (opt->scrollback < 0 || (unsigned)opt->cursor_style > TERM_CURSOR_BAR) + if (opt->scrollback < 0 || opt->scrollback > TERM_SCROLLBACK_MAX || + (unsigned)opt->cursor_style > TERM_CURSOR_BAR) return NULL; const char *name = opt->name && *opt->name ? opt->name : "term"; if (!name_valid(name)) diff --git a/tests/api_args_test.c b/tests/api_args_test.c index 18af728..6c7dfc7 100644 --- a/tests/api_args_test.c +++ b/tests/api_args_test.c @@ -75,6 +75,16 @@ static void test_new_rejects_bad_options(void) assert(!term_new(&opt)); memset(&opt, 0, sizeof(opt)); + opt.scrollback = TERM_SCROLLBACK_MAX + 1; + assert(!term_new(&opt)); + + memset(&opt, 0, sizeof(opt)); + opt.scrollback = TERM_SCROLLBACK_MAX; + struct term *max = term_new(&opt); + assert(max); + term_free(max); + + memset(&opt, 0, sizeof(opt)); opt.cursor_style = (enum term_cursor_style)3; assert(!term_new(&opt)); |
