From 996bf12888925932daace576e09c3053410896f8 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 2 Apr 2026 08:41:46 -0700
Subject: [PATCH] Fixed out of bounds read in XCF image loader (thanks
@Sebasteuo!)
---
src/IMG_xcf.c | 50 ++++++++++++++++++++++++++++++--------------------
1 file changed, 30 insertions(+), 20 deletions(-)
diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
index 59f054d0a..a2db70dc1 100644
--- a/src/IMG_xcf.c
+++ b/src/IMG_xcf.c
@@ -806,20 +806,26 @@ do_layer_surface(SDL_Surface *surface, SDL_IOStream *src, xcf_header *head, xcf_
switch (head->image_type) {
case IMAGE_INDEXED:
for (x = tx; x < tx + ox; x++) {
- *row = ((Uint32)(head->cm_map[*p8 * 3]) << 16);
- *row |= ((Uint32)(head->cm_map[*p8 * 3 + 1]) << 8);
- *row |= ((Uint32)(head->cm_map[*p8++ * 3 + 2]) << 0);
- *row |= ((Uint32)*p8++ << 24);
- row++;
+ Uint8 c = *p8++;
+ Uint8 a = *p8++;
+ if (c < head->cm_num) {
+ *row++ = ((Uint32)(head->cm_map[c * 3]) << 16) |
+ ((Uint32)(head->cm_map[c * 3 + 1]) << 8) |
+ ((Uint32)(head->cm_map[c * 3 + 2]) << 0) |
+ ((Uint32)a << 24);
+ } else {
+ *row++ = 0;
+ }
}
break;
case IMAGE_GREYSCALE:
for (x = tx; x < tx + ox; x++) {
- *row = ((Uint32)*p8 << 16);
- *row |= ((Uint32)*p8 << 8);
- *row |= ((Uint32)*p8++ << 0);
- *row |= ((Uint32)*p8++ << 24);
- row++;
+ Uint8 c = *p8++;
+ Uint8 a = *p8++;
+ *row++ = ((Uint32)c << 16) |
+ ((Uint32)c << 8) |
+ ((Uint32)c << 0) |
+ ((Uint32)a << 24);
}
break;
default:
@@ -837,20 +843,24 @@ do_layer_surface(SDL_Surface *surface, SDL_IOStream *src, xcf_header *head, xcf_
switch (head->image_type) {
case IMAGE_INDEXED:
for (x = tx; x < tx + ox; x++) {
- *row++ = 0xFF000000
- | ((Uint32)(head->cm_map[*p8 * 3]) << 16)
- | ((Uint32)(head->cm_map[*p8 * 3 + 1]) << 8)
- | ((Uint32)(head->cm_map[*p8 * 3 + 2]) << 0);
- p8++;
+ Uint8 c = *p8++;
+ if (c < head->cm_num) {
+ *row++ = 0xFF000000 |
+ ((Uint32)(head->cm_map[c * 3]) << 16) |
+ ((Uint32)(head->cm_map[c * 3 + 1]) << 8) |
+ ((Uint32)(head->cm_map[c * 3 + 2]) << 0);
+ } else {
+ *row++ = 0;
+ }
}
break;
case IMAGE_GREYSCALE:
for (x = tx; x < tx + ox; x++) {
- *row++ = 0xFF000000
- | (((Uint32)(*p8)) << 16)
- | (((Uint32)(*p8)) << 8)
- | (((Uint32)(*p8)) << 0);
- ++p8;
+ Uint8 c = *p8++;
+ *row++ = 0xFF000000 |
+ (((Uint32)c) << 16) |
+ (((Uint32)c) << 8) |
+ (((Uint32)c) << 0);
}
break;
default: