diff --git a/kitty/fonts.c b/kitty/fonts.c index 78ee18a7f..ae49497f7 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -681,7 +681,7 @@ fallback_font(FontGroup *fg, const CPUCell *cpu_cell, const GPUCell *gpu_cell, c bool emoji_presentation = has_emoji_presentation(cpu_cell, lc); char style = emoji_presentation ? 'a' : 'A'; if (bold) style += italic ? 3 : 2; else style += italic ? 1 : 0; - char cell_text[4 * 32] = {style}; + char cell_text[4 * (MAX_NUM_CODEPOINTS_PER_CELL + 8)] = {style}; const size_t cell_text_len = 1 + chars_as_utf8(lc, cell_text + 1, arraysz(cell_text) - 1, ' '); fallback_font_map_t_itr fi = vt_get(&fg->fallback_font_map, cell_text); if (!vt_is_end(fi)) return fi.data->val; diff --git a/kitty/line.h b/kitty/line.h index f9049251c..63d6bfba5 100644 --- a/kitty/line.h +++ b/kitty/line.h @@ -27,6 +27,7 @@ static_assert(sizeof(CellAttrs) == sizeof(uint32_t), "Fix the ordering of CellAt #define WIDTH_MASK (3u) #define DECORATION_MASK (7u) #define SGR_MASK (~(((CellAttrs){.mark=MARK_MASK}).val)) +#define MAX_NUM_CODEPOINTS_PER_CELL 24 // Text presentation selector #define VS15 0xfe0e // Emoji presentation selector diff --git a/kitty/screen.c b/kitty/screen.c index f25f1b92f..f8a03b071 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -845,6 +845,7 @@ add_combining_char(Screen *self, char_type ch, index_type x, index_type y) { CPUCell *cell = cpu_cells + x; if (!cell_has_text(cell) || (cell->is_multicell && cell->y)) return false; // don't allow adding combining chars to a null cell text_in_cell(cell, self->text_cache, self->lc); + if (self->lc->count >= MAX_NUM_CODEPOINTS_PER_CELL) return false; // don't allow too many combining chars to prevent DoS attacks ensure_space_for_chars(self->lc, self->lc->count + 1); self->lc->chars[self->lc->count++] = ch; cell->ch_or_idx = tc_get_or_insert_chars(self->text_cache, self->lc); @@ -1205,11 +1206,12 @@ decode_utf8_safe_string(const uint8_t *src, size_t sz, uint32_t *dest) { } static void -handle_fixed_width_multicell_command(Screen *self, CPUCell mcd, const ListOfChars *lc) { +handle_fixed_width_multicell_command(Screen *self, CPUCell mcd, ListOfChars *lc) { index_type width = mcd.width * mcd.scale; index_type height = mcd.scale; index_type max_height = self->margin_bottom - self->margin_top + 1; if (width > self->columns || height > max_height) return; + lc->count = MIN(lc->count, MAX_NUM_CODEPOINTS_PER_CELL); PREPARE_FOR_DRAW_TEXT; mcd.hyperlink_id = s.cc.hyperlink_id; cell_set_chars(&mcd, self->text_cache, lc);