From e1f942f26a293d1c3f38150e6edf643ccc09a031 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 9 Dec 2025 08:46:00 +0000 Subject: [PATCH 1/3] Add a define for max images and bump to 20 for the moment. --- image.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/image.c b/image.c index 43808785..6e2b1701 100644 --- a/image.c +++ b/image.c @@ -25,6 +25,7 @@ static struct images all_images = TAILQ_HEAD_INITIALIZER(all_images); static u_int all_images_count; +#define MAX_IMAGE_COUNT 20 static void image_free(struct image *im) @@ -111,7 +112,7 @@ image_store(struct screen *s, struct sixel_image *si) TAILQ_INSERT_TAIL(&s->images, im, entry); TAILQ_INSERT_TAIL(&all_images, im, all_entry); - if (++all_images_count == 10/*XXX*/) + if (++all_images_count == MAX_IMAGE_COUNT) image_free(TAILQ_FIRST(&all_images)); return (im); From b8434182c9ead062be8d50a1ff88e98b41108c1f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 27 Apr 2026 13:09:07 +0100 Subject: [PATCH 2/3] Track which list (images or saved_images) each image is on so they can be removed from the correct list when the total image count is reached. Fixes crash reported by xlabai at tencent dot com. --- image.c | 5 +++-- screen.c | 14 ++++++++++++-- tmux.h | 4 +++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/image.c b/image.c index 6e2b1701..a64fc044 100644 --- a/image.c +++ b/image.c @@ -35,7 +35,7 @@ image_free(struct image *im) TAILQ_REMOVE(&all_images, im, all_entry); all_images_count--; - TAILQ_REMOVE(&s->images, im, entry); + TAILQ_REMOVE(im->list, im, entry); sixel_free(im->data); free(im->fallback); free(im); @@ -109,7 +109,8 @@ image_store(struct screen *s, struct sixel_image *si) image_fallback(&im->fallback, im->sx, im->sy); - TAILQ_INSERT_TAIL(&s->images, im, entry); + im->list = &s->images; + TAILQ_INSERT_TAIL(im->list, im, entry); TAILQ_INSERT_TAIL(&all_images, im, all_entry); if (++all_images_count == MAX_IMAGE_COUNT) diff --git a/screen.c b/screen.c index d82784c5..ba3e7c87 100644 --- a/screen.c +++ b/screen.c @@ -633,7 +633,10 @@ screen_reflow(struct screen *s, u_int new_x, u_int *cx, u_int *cy, int cursor) void screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor) { - u_int sx, sy; + u_int sx, sy; +#ifdef ENABLE_SIXEL + struct image *im; +#endif if (SCREEN_IS_ALTERNATE(s)) return; @@ -650,6 +653,8 @@ screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor) #ifdef ENABLE_SIXEL TAILQ_CONCAT(&s->saved_images, &s->images, entry); + TAILQ_FOREACH(im, &s->saved_images, entry) + im->list = &s->saved_images; #endif grid_view_clear(s->grid, 0, 0, sx, sy, 8); @@ -662,7 +667,10 @@ screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor) void screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor) { - u_int sx = screen_size_x(s), sy = screen_size_y(s); + u_int sx = screen_size_x(s), sy = screen_size_y(s); +#ifdef ENABLE_SIXEL + struct image *im; +#endif /* * If the current size is different, temporarily resize to the old size @@ -709,6 +717,8 @@ screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor) #ifdef ENABLE_SIXEL image_free_all(s); TAILQ_CONCAT(&s->images, &s->saved_images, entry); + TAILQ_FOREACH(im, &s->images, entry) + im->list = &s->images; #endif if (s->cx > screen_size_x(s) - 1) diff --git a/tmux.h b/tmux.h index dd62382e..1927fa95 100644 --- a/tmux.h +++ b/tmux.h @@ -936,8 +936,10 @@ struct image { u_int sx; u_int sy; - TAILQ_ENTRY (image) all_entry; + struct images *list; TAILQ_ENTRY (image) entry; + + TAILQ_ENTRY (image) all_entry; }; TAILQ_HEAD(images, image); #endif From c5fb5e8bb026b42a7ba0caa118b3d8ea8a0b54e0 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 20 May 2026 12:17:30 +0100 Subject: [PATCH 3/3] Update CHANGES. --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index bcd1e1c6..cf125fd9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +CHANGES FROM 3.6a TO 3.6b + +* Remove images from the correct list when they are removed while in the + alternate screen (reported by xlabai at tencent dot com). + CHANGES FROM 3.6 TO 3.6a * Fix a buffer overread and an infinite loop in format processing (reported by