vt: fix memory corruption: wcwidth() may return -1

When it did, we called print_insert() with that, which in turn
resulted in a too large size value passed to memmove.
This commit is contained in:
Daniel Eklöf 2019-11-30 00:15:05 +01:00
parent 9551be492c
commit 88c1a8939f
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

26
vt.c
View file

@ -738,19 +738,20 @@ post_print(struct terminal *term)
static inline void static inline void
print_insert(struct terminal *term, int width) print_insert(struct terminal *term, int width)
{ {
if (unlikely(term->insert_mode)) { assert(width > 0);
struct row *row = term->grid->cur_row; if (unlikely(term->insert_mode)) {
const size_t move_count = max(0, term->cols - term->cursor.point.col - width); struct row *row = term->grid->cur_row;
const size_t move_count = max(0, term->cols - term->cursor.point.col - width);
memmove( memmove(
&row->cells[term->cursor.point.col + width], &row->cells[term->cursor.point.col + width],
&row->cells[term->cursor.point.col], &row->cells[term->cursor.point.col],
move_count * sizeof(struct cell)); move_count * sizeof(struct cell));
/* Mark moved cells as dirty */ /* Mark moved cells as dirty */
for (size_t i = term->cursor.point.col + width; i < term->cols; i++) for (size_t i = term->cursor.point.col + width; i < term->cols; i++)
row->cells[i].attrs.clean = 0; row->cells[i].attrs.clean = 0;
} }
} }
static void static void
@ -768,7 +769,8 @@ action_print_utf8(struct terminal *term)
wc = 0; wc = 0;
int width = wcwidth(wc); int width = wcwidth(wc);
print_insert(term, width); if (width > 0)
print_insert(term, width);
row->dirty = true; row->dirty = true;
cell->wc = wc; cell->wc = wc;