From 95dc87cf040e6d79b642e5ff2013ae41da59aba6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 5 Feb 2021 09:12:08 +0530 Subject: [PATCH] Prevent stack overflows when recursing to coalesce frames --- kitty/graphics.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kitty/graphics.c b/kitty/graphics.c index aefcef56b..c6850ee18 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -961,15 +961,16 @@ get_coalesced_frame_data_standalone(const Image *img, const Frame *f, uint8_t *f static CoalescedFrameData -get_coalesced_frame_data(GraphicsManager *self, Image *img, const Frame *f) { +get_coalesced_frame_data_impl(GraphicsManager *self, Image *img, const Frame *f, unsigned count) { CoalescedFrameData ans = {0}; + if (count > 32) return ans; // prevent stack overflows, infinite recursion size_t frame_data_sz; void *frame_data; ImageAndFrame key = {.image_id = img->internal_id, .frame_id = f->id}; if (!read_from_cache(self, key, &frame_data, &frame_data_sz)) return ans; if (!f->base_frame_id) return get_coalesced_frame_data_standalone(img, f, frame_data); Frame *base = frame_for_id(img, f->base_frame_id); if (!base) { free(frame_data); return ans; } - CoalescedFrameData base_data = get_coalesced_frame_data(self, img, base); + CoalescedFrameData base_data = get_coalesced_frame_data_impl(self, img, base, count + 1); if (!base_data.buf) { free(frame_data); return ans; } ComposeData d = { .over_px_sz = f->is_opaque ? 3 : 4, @@ -983,6 +984,11 @@ get_coalesced_frame_data(GraphicsManager *self, Image *img, const Frame *f) { return base_data; } +static inline CoalescedFrameData +get_coalesced_frame_data(GraphicsManager *self, Image *img, const Frame *f) { + return get_coalesced_frame_data_impl(self, img, f, 0); +} + static void update_current_frame(GraphicsManager *self, Image *img, const CoalescedFrameData *data) { bool needs_load = data == NULL;