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;
}