summaryrefslogtreecommitdiff
path: root/src/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/screen.c b/src/screen.c
index 82cd6d3..b99948d 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -808,12 +808,11 @@ void term_screen_set_alternate(struct term *t, bool enabled)
}
}
+/* The caller has checked that requested is not negative. */
static int scrollback_lines(int requested)
{
if (requested == 0)
return TERM_SCROLLBACK_DEFAULT;
- if (requested < 0)
- return 0;
return requested > 1000000 ? 1000000 : requested;
}
@@ -841,16 +840,35 @@ bool term_tables_ready(void)
return atomic_load_explicit(&tables_state, memory_order_relaxed) == 2;
}
+/* A name is 1 to 63 printable ASCII bytes. DCS replies echo it. */
+static bool name_valid(const char *s)
+{
+ for (size_t i = 0; s[i]; i++) {
+ unsigned char c = (unsigned char)s[i];
+ if (i >= 63 || c < 0x20 || c > 0x7e)
+ return false;
+ }
+ return true;
+}
+
struct term *term_new(const struct term_options *opt)
{
tables_init();
static const struct term_options defaults;
if (!opt)
opt = &defaults;
- int cols = opt->size.x < 1 ? 80 : opt->size.x;
- int rows = opt->size.y < 1 ? 24 : opt->size.y;
- if (cols > TERM_MAX_COLS)
- cols = TERM_MAX_COLS;
+ for (size_t i = 0; i < sizeof(opt->reserved) / sizeof(opt->reserved[0]); i++)
+ if (opt->reserved[i])
+ 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)
+ return NULL;
+ const char *name = opt->name && *opt->name ? opt->name : "term";
+ if (!name_valid(name))
+ return NULL;
+ int cols = opt->size.x == 0 ? 80 : opt->size.x;
+ int rows = opt->size.y == 0 ? 24 : opt->size.y;
static _Atomic uint64_t next_serial = 1;
struct term *t = calloc(1, sizeof(*t));
@@ -860,6 +878,7 @@ struct term *term_new(const struct term_options *opt)
free(t);
return NULL;
}
+ memcpy(t->name, name, strlen(name) + 1);
atomic_init(&t->writer_tid, 0);
t->write_depth = 0;
t->serial = atomic_fetch_add_explicit(&next_serial, 1, memory_order_relaxed);
@@ -900,14 +919,14 @@ struct term *term_new(const struct term_options *opt)
t->cur_fg = TERM_COLOR_FG;
t->cur_bg = TERM_COLOR_BG;
t->cursor_visible = true;
- t->default_cursor_style = opt->cursor_style > TERM_CURSOR_BAR ? TERM_CURSOR_BLOCK : opt->cursor_style;
+ t->default_cursor_style = opt->cursor_style;
t->default_cursor_blink = !opt->cursor_steady;
t->cursor_style = t->default_cursor_style;
t->cursor_blink = t->default_cursor_blink;
t->autowrap = true;
t->charsets[0] = t->charsets[1] = 'B';
t->saved = term_saved_cursor_initial();
- memcpy(t->tcap_name, "wsap_term", sizeof("wsap_term"));
+ memcpy(t->tcap_name, t->name, sizeof(t->name));
term_tabs_default(t);
t->full_gen = 1;
memset(t->text_width.lo, 0xFF, sizeof(t->text_width.lo));
@@ -1529,10 +1548,8 @@ bool term_resize(struct term *t, struct term_vector2i size)
return false;
int cols = size.x;
int rows = size.y;
- if (cols < 1 || rows < 1)
+ if (cols < 1 || rows < 1 || cols > TERM_MAX_COLS)
return false;
- if (cols > TERM_MAX_COLS)
- cols = TERM_MAX_COLS;
term_write_begin(t);
if (cols == t->cols && rows == t->rows) {
term_write_end(t);