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

From 3ce6cb6f968427cd1041f9dc7b0bb6024fd4c782 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[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.

This fix backported to SDL2 from 6c804082117c95c24b3d3af886319e8c21fcd8e0.
---
 src/IMG_xcf.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
index 4e9f1578..f7680491 100644
--- a/src/IMG_xcf.c
+++ b/src/IMG_xcf.c
@@ -537,7 +537,7 @@ static unsigned char * load_xcf_tile_none (SDL_RWops * src, Uint64 len, int bpp,
 }
 
 static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 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;
 
@@ -552,6 +552,11 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 len, int bpp,
   SDL_RWread (src, t, 1, (size_t)len); /* reallen */
 
   data = (unsigned char *) SDL_calloc (1, x*y*bpp);
+  if (!data) {
+    SDL_free(load);
+    return NULL;
+  }
+  data_end = data + x*y*bpp;
   for (i = 0; i < bpp; i++) {
     d    = data + i;
     size = x*y;
@@ -578,6 +583,9 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 len, int bpp,
         size -= length;
 
         while (length-- > 0) {
+          if (d >= data_end) {
+            break;
+          }
           *d = *t++;
           d += bpp;
         }
@@ -600,6 +608,9 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 len, int bpp,
         val = *t++;
 
         for (j = 0; j < length; j++) {
+          if (d >= data_end) {
+            break;
+          }
           *d = val;
           d += bpp;
         }