sixel: fix double free caused by bad free() in sixel_colors_set()

sixel_color_set() is called when the number of (sixel) color registers
is changed.

It frees the current palette, and changes the “palette size” variable.

Originally, we only had a single palette. This is the one free:d by
sixel_color_set().

Later, we added support for private vs. shared palettes. With this
change, we now have one palette that is “never” free:d (the shared
one), and a private palette that is always free:d after a sixel has
been emitted.

‘sixel.palette’ is a pointer to the palette currently in use, and
should only be accessed **while emitting a sixel**.

This is the pointer sixel_color_set() free:d. So for example, if
‘sixel.palette’ pointed to the shared palette, we’d free the shared
palette. But, we didn’t reset ‘sixel.shared_palette’, causing a double
free later on.

Closes #427
This commit is contained in:
Daniel Eklöf 2021-03-30 11:08:03 +02:00
parent 0720b3177a
commit 6e782271ff
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 7 additions and 2 deletions

View file

@ -34,6 +34,9 @@
* Reverted _"Consumed modifiers are no longer sent to the client
application"_ (https://codeberg.org/dnkl/foot/issues/425).
* Crash caused by a double free originating in `XTSMGRAPHICS` - set
number of color registers
(https://codeberg.org/dnkl/foot/issues/427).
### Security

View file

@ -1344,8 +1344,10 @@ sixel_colors_set(struct terminal *term, unsigned count)
unsigned new_palette_size = min(max(2, count), SIXEL_MAX_COLORS);
LOG_DBG("sixel palette size set to %u", new_palette_size);
free(term->sixel.palette);
term->sixel.palette = NULL;
free(term->sixel.private_palette);
free(term->sixel.shared_palette);
term->sixel.private_palette = NULL;
term->sixel.shared_palette = NULL;
term->sixel.palette_size = new_palette_size;
sixel_colors_report_current(term);