SDL_image: xcf: Fix heap-buffer-overflow READ in XCF RLE decoder (CWE-122) (d85c6)

From d85c6118e2cad9b4c24531a67bd900d64e19091f Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Mon, 6 Apr 2026 15:09:55 -0400
Subject: [PATCH] xcf: Fix heap-buffer-overflow READ in XCF RLE decoder
 (CWE-122)

Add destination pointer bounds check in load_xcf_tile_rle.

(manual backport of commit 3ce6cb6f968427cd1041f9dc7b0bb6024fd4c782)
---
 IMG_xcf.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/IMG_xcf.c b/IMG_xcf.c
index d4a740fe..0216ab94 100644
--- a/IMG_xcf.c
+++ b/IMG_xcf.c
@@ -544,7 +544,7 @@ static unsigned char * load_xcf_tile_none (SDL_RWops * src, Uint32 len, int bpp,
 }
 
 static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp, int x, int y) {
-  unsigned char * load, * t, * data, * d;
+  unsigned char * load, * t, * data, * data_end, * d;
   int i, size, count, j, length;
   unsigned char val;
 
@@ -559,6 +559,11 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp,
   SDL_RWread (src, t, 1, len); /* reallen */
 
   data = (unsigned char *) calloc (1, x*y*bpp);
+  if (!data) {
+    free(load);
+    return NULL;
+  }
+  data_end = data + x*y*bpp;
   for (i = 0; i < bpp; i++) {
     d    = data + i;
     size = x*y;
@@ -585,6 +590,9 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp,
 	size -= length;
 
 	while (length-- > 0) {
+	  if (d >= data_end) {
+	    break;
+	  }
 	  *d = *t++;
 	  d += bpp;
 	}
@@ -607,6 +615,9 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp,
 	val = *t++;
 
 	for (j = 0; j < length; j++) {
+	  if (d >= data_end) {
+	    break;
+	  }
 	  *d = val;
 	  d += bpp;
 	}