Limit max number of combining chars per cell

This commit is contained in:
Kovid Goyal 2025-02-12 08:27:25 +05:30
parent e7a40300d1
commit 1c00ae80e6
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
3 changed files with 5 additions and 2 deletions

View file

@ -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;

View file

@ -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

View file

@ -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);