diff options
Diffstat (limited to 'src/screen.c')
| -rw-r--r-- | src/screen.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/src/screen.c b/src/screen.c index 87d6f2c..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,22 +840,45 @@ 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)); if (!t) return NULL; - atomic_init(&t->seq, 0); + if (!term_mutex_init(&t->write_lock)) { + 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); @@ -871,11 +893,13 @@ struct term *term_new(const struct term_options *opt) t->next_row_uid = 1; if (!screen_setup(&t->scr, cols, rows, &t->next_row_uid)) { + term_mutex_destroy(&t->write_lock); free(t); return NULL; } if (!term_hist_init(&t->hist, t->sb_capacity, 0)) { screen_free(&t->scr); + term_mutex_destroy(&t->write_lock); free(t); return NULL; } @@ -895,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)); @@ -932,6 +956,7 @@ void term_free(struct term *t) free(t->tabs); term_osc_cleanup(t); term_gstore_free(t->gstore); + term_mutex_destroy(&t->write_lock); free(t); } @@ -1523,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); |
