Bug#1134510: trixie-pu: package libsdl2-image/2.8.8+dfsg-1+deb13u1

Simon McVittie <[email protected]>
Newsgroups gmane.linux.debian.devel.release
Message-ID <aor_d5yCv_ori6I___20087.0858550601$1787494426$gmane$org@definition.pseudorandom.co.uk>
Control: tags -1 - moreinfo

[ Reason ]
Fix CVE-2026-35444 and various other out-of-bounds accesses when parsing 
malformed/crafted image files

[ Impact ]
If not fixed, games/applications that load untrusted images using 
SDL2_image could be subject to denial-of-service (crash) or possibly 
exploitable.

[ Tests ]
autopkgtest (automated smoke-tests loading images in various formats) 
passes. Some sample games from trixie that depend on this library 
(assaultcube, wesnoth) appear to run normally. As with SDL3_image, I 
haven't attempted to load malformed/crafted/malicious images.

A test-build (equivalent except for the changelog) is available from 
<https://people.debian.org/~smcv/13.7/libsdl2-image/testbuild/>.

[ Risks ]
Could regress image loading in SDL2 games, especially in weird/rare 
formats. I suspect that in practice, none of our games/applications rely 
on being able to load the affected formats (*maybe* GIF and TGA).

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
All changes are robustness fixes from upstream. Most are fixed in 3.4.2 
or 3.4.4 upstream. One is not in an upstream release yet, I backported 
it into forky already.

[ Other info ]
Related to https://bugs.debian.org/1145180 for libsdl3-image, a newer 
branch of the same codebase.

Compared with the earlier proposal from Aquila Macedo Costa, this one 
addresses all known out-of-bounds accesses, not just the one that (for 
whatever reason) had a CVE ID allocated upstream.
libsdl2-image_2.8.8+dfsg-1+deb13u1.diff (text/x-diff, 39 KB)
diffstat for libsdl2-image-2.8.8+dfsg libsdl2-image-2.8.8+dfsg

 debian/changelog                                                               |   38 ++++
 debian/control                                                                 |    2 
 debian/gbp.conf                                                                |    2 
 debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch |   33 +++
 debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch     |   33 +++
 debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch                    |   31 +++
 debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch |   90 ++++++++++
 debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch |   25 ++
 debian/patches/series                                                          |   11 +
 debian/patches/tga-reject-images-with-zero-width-or-height.patch               |   39 ++++
 debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch |   24 ++
 debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch |   60 ++++++
 debian/patches/xcf-Permit-empty-strings-in-read_string.patch                   |   34 +++
 debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch |   39 ++++
 debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch |   43 ++++
 src/IMG_gif.c                                                                  |    6 
 src/IMG_lbm.c                                                                  |    7 
 src/IMG_tga.c                                                                  |    4 
 src/IMG_xcf.c                                                                  |   87 +++++++--
 src/IMG_xpm.c                                                                  |   11 -
 20 files changed, 587 insertions(+), 32 deletions(-)

diff -Nru libsdl2-image-2.8.8+dfsg/debian/changelog libsdl2-image-2.8.8+dfsg/debian/changelog
--- libsdl2-image-2.8.8+dfsg/debian/changelog	2025-03-04 09:59:59.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/debian/changelog	2026-08-23 14:45:36.000000000 +0100
@@ -1,3 +1,41 @@
+libsdl2-image (2.8.8+dfsg-1+deb13u1) trixie; urgency=medium
+
+  [ Aquila Macedo Costa ]
+  * d/p/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch:
+    Import upstream patch for CVE-2026-35444 (Closes: #1133010)
+  * d/patches: Add selected upstream malformed-image parser robustness fixes:
+    - d/p/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch:
+      check XPM color hash entries before use
+    - d/p/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch:
+      fix LBM palette overflow
+    - d/p/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch:
+      add XCF RLE decoder bounds checks
+    - d/p/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch,
+      d/p/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch:
+      add XCF do_layer_surface tile bounds check, report invalid XCF tile data
+      through SDL_SetError()
+    - d/p/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch:
+      check XCF hierarchy read failures before dereferencing
+    - d/p/tga-reject-images-with-zero-width-or-height.patch:
+      reject TGA images with zero width or height
+    - d/p/Fixed-out-of-bound-read-in-GIF-decoder.patch:
+      fix out-of-bounds reads in the GIF decoder
+
+  [ Simon McVittie ]
+  * d/control, d/gbp.conf: Branch for trixie
+  * d/patches: Improve patch metadata: add CVE ID, Debian bug number,
+    upstream commit references, etc.
+  * d/patches: Re-export patches with their mechanically-generated names and
+    apply them in the same order that upstream did, to make it more obvious
+    how this version compares with 2.8.12
+  * d/patches: Add additional robustness fixes for parsing malformed images:
+    - d/p/xcf-Permit-empty-strings-in-read_string.patch:
+      Avoid an out-of-bounds write if XCF files contain a zero-length string
+    - d/p/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch:
+      Harden XCF parsing against extremely long strings
+
+ -- Simon McVittie <[email protected]>  Sun, 23 Aug 2026 14:45:36 +0100
+
 libsdl2-image (2.8.8+dfsg-1) unstable; urgency=medium
 
   * New upstream stable release
diff -Nru libsdl2-image-2.8.8+dfsg/debian/control libsdl2-image-2.8.8+dfsg/debian/control
--- libsdl2-image-2.8.8+dfsg/debian/control	2025-03-04 09:59:59.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/debian/control	2026-08-23 14:45:36.000000000 +0100
@@ -15,7 +15,7 @@
 Standards-Version: 4.7.2
 Homepage: https://github.com/libsdl-org/SDL_image
 Vcs-Browser: https://salsa.debian.org/sdl-team/libsdl2-image
-Vcs-Git: https://salsa.debian.org/sdl-team/libsdl2-image.git
+Vcs-Git: https://salsa.debian.org/sdl-team/libsdl2-image.git -b debian/trixie
 
 Package: libsdl2-image-2.0-0
 Architecture: any
diff -Nru libsdl2-image-2.8.8+dfsg/debian/gbp.conf libsdl2-image-2.8.8+dfsg/debian/gbp.conf
--- libsdl2-image-2.8.8+dfsg/debian/gbp.conf	2025-03-04 09:59:59.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/debian/gbp.conf	2026-08-23 14:45:36.000000000 +0100
@@ -1,6 +1,6 @@
 [DEFAULT]
 pristine-tar = True
-debian-branch = debian/latest
+debian-branch = debian/trixie
 upstream-branch = upstream/latest
 
 [tag]
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,31 @@
+From: Sam Lantinga <[email protected]>
+Date: Wed, 29 Apr 2026 08:18:09 -0700
+Subject: Fixed out of bound read in GIF decoder
+
+Fixes https://github.com/libsdl-org/SDL_image/issues/724
+
+(cherry picked from commit e2b258927d11438cbf4ee55a5c4ff059a6e32d08)
+(cherry picked from commit 2c02f371f55a2f74a291639d95761066ac2afff0)
+Bug: https://github.com/libsdl-org/SDL_image/issues/724
+Origin: upstream, 2.8.12, commit:38fdd07d43a01b604fffb7453bff3ae2e9fd339a
+---
+ src/IMG_gif.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/IMG_gif.c b/src/IMG_gif.c
+index 58667e9..240bb7d 100644
+--- a/src/IMG_gif.c
++++ b/src/IMG_gif.c
+@@ -469,8 +469,10 @@ GetCode(SDL_RWops *src, int code_size, int flag, State_t * state)
+                 RWSetMsg("ran off the end of my bits");
+             return -1;
+         }
+-        state->buf[0] = state->buf[state->last_byte - 2];
+-        state->buf[1] = state->buf[state->last_byte - 1];
++        if (state->last_byte > 2) {
++            state->buf[0] = state->buf[state->last_byte - 2];
++            state->buf[1] = state->buf[state->last_byte - 1];
++        }
+ 
+         if ((ret = GetDataBlock(src, &state->buf[2], state)) > 0)
+             count = (unsigned char) ret;
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,90 @@
+From: Sam Lantinga <[email protected]>
+Date: Thu, 2 Apr 2026 08:41:46 -0700
+Subject: Fixed out of bounds read in XCF image loader (thanks @Sebasteuo!)
+
+(cherry picked from commit f55d589ba5de11c724afcdcae80b56bf26d91d15)
+(cherry picked from commit a1a06276a51ca7e6e63908b200df8a278d8c5039)
+Origin: upstream, 2.8.10, commit:fa9ffb8cced56aba2a2ab27d7c4388278e6b70c0
+Bug: https://github.com/libsdl-org/SDL_image/security/advisories/GHSA-gq8w-x74c-h6p7
+Bug-CVE: https://security-tracker.debian.org/tracker/CVE-2026-35444
+Bug-Debian: https://bugs.debian.org/1133010
+---
+ 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 95c1526..a1683ec 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -716,20 +716,26 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * 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:
+@@ -747,20 +753,24 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * 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:
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,33 @@
+From: Jorge Barredo Ferreira <[email protected]>
+Date: Mon, 6 Apr 2026 19:30:53 +0200
+Subject: Fix heap-buffer-overflow READ in XCF do_layer_surface (CWE-122)
+
+Add bounds check for tile buffer access in do_layer_surface.
+
+(cherry picked from commit 5b0d414cae99b2e162a1e46ecba4fcd7ac8c5d85)
+Origin: https://github.com/libsdl-org/SDL_image/pull/719
+Applied-upstream: 2.8.12, commit:3796a0bc0c45c1a3fed4b43c697e75c5061d4d67
+---
+ src/IMG_xcf.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index ed7d203..f067746 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -700,6 +700,15 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_
+ 
+             p8 = tile;
+             p = (Uint32 *) p8;
++
++            /* Bounds check: reject layer if tile data exceeds buffer */
++            if ((Uint64)ox * oy * hierarchy->bpp > (Uint64)(hierarchy->width * hierarchy->height * hierarchy->bpp)) {
++                free_xcf_tile(tile);
++                free_xcf_level(level);
++                free_xcf_hierarchy(hierarchy);
++                return 1;
++            }
++
+             for (y = ty; y < ty + oy; y++) {
+                 if ((y >= (Uint32)surface->h) || ((tx+ox) > (Uint32)surface->w)) {
+                     break;
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,33 @@
+From: Jorge Barredo Ferreira <[email protected]>
+Date: Mon, 6 Apr 2026 19:29:38 +0200
+Subject: Fix heap-buffer-overflow WRITE in LBM palette (CWE-122)
+
+When nbplanes > 8 without HAM flag, nbrcolorsfinal exceeds 256,
+causing writes past the palette buffer. Reject nbplanes > 8 for
+paletted images.
+
+(cherry picked from commit 2fe0746733c9f280d2c344bce231dd70fdf3bdb8)
+Origin: https://github.com/libsdl-org/SDL_image/pull/717
+Applied-upstream: 2.8.12, commit:695a166b94d772e9da4597682858dc27f870a013
+---
+ src/IMG_lbm.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/IMG_lbm.c b/src/IMG_lbm.c
+index 66215e6..bb10f90 100644
+--- a/src/IMG_lbm.c
++++ b/src/IMG_lbm.c
+@@ -232,6 +232,13 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
+ 
+     nbplanes = bmhd.planes;
+ 
++    /* Sanity check: nbplanes must not exceed 8 for paletted images.
++       Higher values cause 1<<nbplanes to exceed the 256-entry palette. */
++    if ( !pbm && nbplanes > 8 && nbplanes != 24 && flagHAM == 0 ) {
++        SDL_SetError("LBM: invalid number of bitplanes (%u)", nbplanes);
++        goto done;
++    }
++
+     if ( pbm )                         /* File format : 'Packed Bitmap' */
+     {
+         bytesperline *= 8;
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch libsdl2-image-2.8.8+dfsg/debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,25 @@
+From: Ozkan Sezer <[email protected]>
+Date: Wed, 13 May 2026 14:51:47 +0300
+Subject: IMG_xcf.c (read_string): add back the positive string size check
+
+[Otherwise a claimed size >= 2**31 bytes could lead to underflow. -smcv]
+
+(cherry picked from commit cdbe3bf771606a3502c1c5994812bfc48d4814a0)
+Origin: upstream, 2.8.12, commit:d23a437d9b620cfca437ffa5aa332799435973bd
+---
+ src/IMG_xcf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index b513448..4e2e635 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -241,7 +241,7 @@ static char * read_string (SDL_RWops * src) {
+     return data;
+   }
+ 
+-  if ((Sint32)tmp <= remaining) {
++  if ((Sint32)tmp > 0 && (Sint32)tmp <= remaining) {
+     data = (char *) SDL_malloc (sizeof (char) * tmp);
+     if (data) {
+       SDL_RWread(src, data, tmp, 1);
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/series libsdl2-image-2.8.8+dfsg/debian/patches/series
--- libsdl2-image-2.8.8+dfsg/debian/patches/series	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/series	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,11 @@
+Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch
+xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch
+Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch
+xcf-Permit-empty-strings-in-read_string.patch
+Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch
+xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch
+xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch
+xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch
+tga-reject-images-with-zero-width-or-height.patch
+Fixed-out-of-bound-read-in-GIF-decoder.patch
+IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/tga-reject-images-with-zero-width-or-height.patch libsdl2-image-2.8.8+dfsg/debian/patches/tga-reject-images-with-zero-width-or-height.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/tga-reject-images-with-zero-width-or-height.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/tga-reject-images-with-zero-width-or-height.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,39 @@
+From: Jorge Barredo Ferreira <[email protected]>
+Date: Thu, 23 Apr 2026 11:20:40 -0700
+Subject: tga: reject images with zero width or height
+
+When SDL_CreateSurface() is called with w=0 or h=0 it may return a
+non-NULL surface but with a NULL pixels pointer (zero-size allocation).
+Subsequent code at IMG_LoadTGA_IO accesses img->pixels unconditionally,
+resulting in undefined behavior: UBSan reports "applying zero offset to
+null pointer" for the expression (Uint8*)img->pixels + (h-1)*img->pitch
+when pitch is 0.
+
+Reject zero-dimension images early before creating the surface.
+
+CWE-476 (NULL Pointer Dereference)
+Found by: NORAI fuzzer (libFuzzer + UBSan)
+PoC: poc_sdl007_tga_null_pixels.tga
+
+(cherry picked from commit 4ba58feebaf87ad80b8ab3971ea8f82132884c54)
+(cherry picked from commit 9f1318e7c112493fcd224eafe8809d4001d1bb33)
+Origin: upstream, 2.8.12, commit:67c8f531ad09ddc0e6d4c7b1468c863235711ed4
+---
+ src/IMG_tga.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/IMG_tga.c b/src/IMG_tga.c
+index 537f2ee..8d6d52f 100644
+--- a/src/IMG_tga.c
++++ b/src/IMG_tga.c
+@@ -178,6 +178,10 @@ SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src)
+ 
+     w = LE16(hdr.width);
+     h = LE16(hdr.height);
++    if (w == 0 || h == 0) {
++        error = "TGA image with zero width or height";
++        goto error;
++    }
+     img = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, format);
+     if (img == NULL) {
+         error = "Out of memory";
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,24 @@
+From: "Ryan C. Gordon" <[email protected]>
+Date: Mon, 6 Apr 2026 14:58:56 -0400
+Subject: xcf: Added an SDL_SetError when rejecting out-of-bounds tile data.
+
+(cherry picked from commit 1aedddcbd205c4e1ea0f99fdb2c785acc8e2489b)
+
+[This fixes incorrect error reporting by #719 -smcv]
+Origin: upstream, 2.8.12, commit:cde1749f5223d7b99750fb79e7822fe11797a2a8
+---
+ src/IMG_xcf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index f067746..4e9f157 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -703,6 +703,7 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_
+ 
+             /* Bounds check: reject layer if tile data exceeds buffer */
+             if ((Uint64)ox * oy * hierarchy->bpp > (Uint64)(hierarchy->width * hierarchy->height * hierarchy->bpp)) {
++                SDL_SetError("Gimp image invalid tile");
+                 free_xcf_tile(tile);
+                 free_xcf_level(level);
+                 free_xcf_hierarchy(hierarchy);
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,60 @@
+From: "Ryan C. Gordon" <[email protected]>
+Date: Mon, 6 Apr 2026 15:09:55 -0400
+Subject: 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.
+
+(cherry picked from commit 3ce6cb6f968427cd1041f9dc7b0bb6024fd4c782)
+Origin: backport, https://github.com/libsdl-org/SDL_image/pull/720
+Applied-upstream: 2.8.12, commit:f4a54104604dacd44bd43a4502c70926ca79902f
+---
+ 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 4e9f157..f768049 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;
+         }
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch libsdl2-image-2.8.8+dfsg/debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,39 @@
+From: Jorge Barredo Ferreira <[email protected]>
+Date: Tue, 7 Apr 2026 17:16:58 +0200
+Subject: xcf: fix null pointer dereference when read_xcf_hierarchy() fails
+
+read_xcf_hierarchy() can return NULL when SDL_calloc() fails or when
+SDL_ReadU32BE() fails to read the width/height/bpp fields. The return
+value was not checked before dereferencing hierarchy->bpp at line 755
+in do_layer_surface(), leading to a null pointer dereference.
+
+Add a NULL check immediately after the call to return early with an
+error in that case.
+
+CWE-476 (NULL Pointer Dereference)
+Found by: NORAI fuzzer (libFuzzer + ASan/UBSan)
+PoC: poc_sdl006_xcf_hierarchy_null.xcf
+
+(cherry picked from commit 336fb104494815984250c40f8ee6bd1325b7ba1e)
+(cherry picked from commit be7fee9064ed15d88e0bc573c018045daacfd01a)
+Origin: https://github.com/libsdl-org/SDL_image/pull/722
+Applied-upstream: 2.8.12, commit:aa03c0f5d0a2a8ba42c719de672650a0dda939e2
+---
+ src/IMG_xcf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index f768049..b513448 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -666,6 +666,10 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_
+ 
+     SDL_RWseek(src, layer->hierarchy_file_offset, RW_SEEK_SET);
+     hierarchy = read_xcf_hierarchy(src, head);
++    if (!hierarchy) {
++        SDL_SetError("Failed to read XCF image hierarchy");
++        return 1;
++    }
+ 
+     if (hierarchy->bpp > 4) {  /* unsupported. */
+         SDL_Log("Unknown Gimp image bpp (%u)\n", (unsigned int) hierarchy->bpp);
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Permit-empty-strings-in-read_string.patch libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Permit-empty-strings-in-read_string.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Permit-empty-strings-in-read_string.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Permit-empty-strings-in-read_string.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,34 @@
+From: "Ryan C. Gordon" <[email protected]>
+Date: Mon, 6 Apr 2026 14:53:45 -0400
+Subject: xcf: Permit empty strings in read_string().
+
+Reference Issue #716.
+
+(cherry picked from commit 1da905ae95748edbf063102574be5f25ff42ae39)
+Origin: upstream, 2.8.12, commit:2d2928376e1e044fd9e501d25e6e39e71b8fb85c
+Bug: https://github.com/libsdl-org/SDL_image/issues/716
+---
+ src/IMG_xcf.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index a1683ec..ed7d203 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -233,7 +233,15 @@ static char * read_string (SDL_RWops * src) {
+ 
+   tmp = SDL_ReadBE32(src);
+   remaining = SDL_RWsize(src) - SDL_RWtell(src);
+-  if (tmp > 0 && (Sint32)tmp <= remaining) {
++  if (tmp == 0) {
++    data = (char *) SDL_malloc(1);
++    if (data) {
++      data[0] = 0;
++    }
++    return data;
++  }
++
++  if ((Sint32)tmp <= remaining) {
+     data = (char *) SDL_malloc (sizeof (char) * tmp);
+     if (data) {
+       SDL_RWread(src, data, tmp, 1);
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch libsdl2-image-2.8.8+dfsg/debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,43 @@
+From: "Ryan C. Gordon" <[email protected]>
+Date: Mon, 6 Apr 2026 14:24:56 -0400
+Subject: xpm: Remove QUICK_COLORHASH,
+ replace it with inline code that checks for NULL.
+
+Closes #721.
+
+(cherry picked from commit bc17bc7c6a2767e342ebb6d3fd37c8e323c8dd70)
+Origin: upstream, 2.8.12, commit:5df1ec7d9dda53c02f251971e2169690c50211d8
+Bug: https://github.com/libsdl-org/SDL_image/issues/715
+---
+ src/IMG_xpm.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/src/IMG_xpm.c b/src/IMG_xpm.c
+index 2b2f119..09441b9 100644
+--- a/src/IMG_xpm.c
++++ b/src/IMG_xpm.c
+@@ -157,9 +157,6 @@ static int add_colorhash(struct color_hash *hash,
+     return 1;
+ }
+ 
+-/* fast lookup that works if cpp == 1 */
+-#define QUICK_COLORHASH(hash, key) ((hash)->table[*(Uint8 *)(key)]->color)
+-
+ static Uint32 get_colorhash(struct color_hash *hash, const char *key, int cpp)
+ {
+     struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)];
+@@ -1132,9 +1129,11 @@ static SDL_Surface *load_xpm(char **xpm, SDL_RWops *src, SDL_bool force_32bit)
+         if (indexed) {
+             /* optimization for some common cases */
+             if (cpp == 1)
+-                for (x = 0; x < w; x++)
+-                    dst[x] = (Uint8)QUICK_COLORHASH(colors,
+-                                 line + x);
++                for (x = 0; x < w; x++) {
++                    /* fast lookup that works if cpp == 1 */
++                    const struct hash_entry *entry = colors->table[*(Uint8 *)(line + x)];
++                    dst[x] = entry ? (Uint8) entry->color : 0;
++                }
+             else
+                 for (x = 0; x < w; x++)
+                     dst[x] = (Uint8)get_colorhash(colors,
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_gif.c libsdl2-image-2.8.8+dfsg/src/IMG_gif.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_gif.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_gif.c	2026-08-23 15:03:00.000000000 +0100
@@ -469,8 +469,10 @@
                 RWSetMsg("ran off the end of my bits");
             return -1;
         }
-        state->buf[0] = state->buf[state->last_byte - 2];
-        state->buf[1] = state->buf[state->last_byte - 1];
+        if (state->last_byte > 2) {
+            state->buf[0] = state->buf[state->last_byte - 2];
+            state->buf[1] = state->buf[state->last_byte - 1];
+        }
 
         if ((ret = GetDataBlock(src, &state->buf[2], state)) > 0)
             count = (unsigned char) ret;
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_lbm.c libsdl2-image-2.8.8+dfsg/src/IMG_lbm.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_lbm.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_lbm.c	2026-08-23 15:03:00.000000000 +0100
@@ -232,6 +232,13 @@
 
     nbplanes = bmhd.planes;
 
+    /* Sanity check: nbplanes must not exceed 8 for paletted images.
+       Higher values cause 1<<nbplanes to exceed the 256-entry palette. */
+    if ( !pbm && nbplanes > 8 && nbplanes != 24 && flagHAM == 0 ) {
+        SDL_SetError("LBM: invalid number of bitplanes (%u)", nbplanes);
+        goto done;
+    }
+
     if ( pbm )                         /* File format : 'Packed Bitmap' */
     {
         bytesperline *= 8;
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_tga.c libsdl2-image-2.8.8+dfsg/src/IMG_tga.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_tga.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_tga.c	2026-08-23 15:03:00.000000000 +0100
@@ -178,6 +178,10 @@
 
     w = LE16(hdr.width);
     h = LE16(hdr.height);
+    if (w == 0 || h == 0) {
+        error = "TGA image with zero width or height";
+        goto error;
+    }
     img = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, format);
     if (img == NULL) {
         error = "Out of memory";
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_xcf.c libsdl2-image-2.8.8+dfsg/src/IMG_xcf.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_xcf.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_xcf.c	2026-08-23 15:03:00.000000000 +0100
@@ -233,7 +233,15 @@
 
   tmp = SDL_ReadBE32(src);
   remaining = SDL_RWsize(src) - SDL_RWtell(src);
-  if (tmp > 0 && (Sint32)tmp <= remaining) {
+  if (tmp == 0) {
+    data = (char *) SDL_malloc(1);
+    if (data) {
+      data[0] = 0;
+    }
+    return data;
+  }
+
+  if ((Sint32)tmp > 0 && (Sint32)tmp <= remaining) {
     data = (char *) SDL_malloc (sizeof (char) * tmp);
     if (data) {
       SDL_RWread(src, data, tmp, 1);
@@ -529,7 +537,7 @@
 }
 
 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;
 
@@ -544,6 +552,11 @@
   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;
@@ -570,6 +583,9 @@
         size -= length;
 
         while (length-- > 0) {
+          if (d >= data_end) {
+            break;
+          }
           *d = *t++;
           d += bpp;
         }
@@ -592,6 +608,9 @@
         val = *t++;
 
         for (j = 0; j < length; j++) {
+          if (d >= data_end) {
+            break;
+          }
           *d = val;
           d += bpp;
         }
@@ -647,6 +666,10 @@
 
     SDL_RWseek(src, layer->hierarchy_file_offset, RW_SEEK_SET);
     hierarchy = read_xcf_hierarchy(src, head);
+    if (!hierarchy) {
+        SDL_SetError("Failed to read XCF image hierarchy");
+        return 1;
+    }
 
     if (hierarchy->bpp > 4) {  /* unsupported. */
         SDL_Log("Unknown Gimp image bpp (%u)\n", (unsigned int) hierarchy->bpp);
@@ -692,6 +715,16 @@
 
             p8 = tile;
             p = (Uint32 *) p8;
+
+            /* Bounds check: reject layer if tile data exceeds buffer */
+            if ((Uint64)ox * oy * hierarchy->bpp > (Uint64)(hierarchy->width * hierarchy->height * hierarchy->bpp)) {
+                SDL_SetError("Gimp image invalid tile");
+                free_xcf_tile(tile);
+                free_xcf_level(level);
+                free_xcf_hierarchy(hierarchy);
+                return 1;
+            }
+
             for (y = ty; y < ty + oy; y++) {
                 if ((y >= (Uint32)surface->h) || ((tx+ox) > (Uint32)surface->w)) {
                     break;
@@ -716,20 +749,26 @@
                     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:
@@ -747,20 +786,24 @@
                     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:
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_xpm.c libsdl2-image-2.8.8+dfsg/src/IMG_xpm.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_xpm.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_xpm.c	2026-08-23 15:03:00.000000000 +0100
@@ -157,9 +157,6 @@
     return 1;
 }
 
-/* fast lookup that works if cpp == 1 */
-#define QUICK_COLORHASH(hash, key) ((hash)->table[*(Uint8 *)(key)]->color)
-
 static Uint32 get_colorhash(struct color_hash *hash, const char *key, int cpp)
 {
     struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)];
@@ -1132,9 +1129,11 @@
         if (indexed) {
             /* optimization for some common cases */
             if (cpp == 1)
-                for (x = 0; x < w; x++)
-                    dst[x] = (Uint8)QUICK_COLORHASH(colors,
-                                 line + x);
+                for (x = 0; x < w; x++) {
+                    /* fast lookup that works if cpp == 1 */
+                    const struct hash_entry *entry = colors->table[*(Uint8 *)(line + x)];
+                    dst[x] = entry ? (Uint8) entry->color : 0;
+                }
             else
                 for (x = 0; x < w; x++)
                     dst[x] = (Uint8)get_colorhash(colors,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.