summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/term/term.h5
-rw-r--r--src/screen.c9
-rw-r--r--tests/api_args_test.c10
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));