giflib: update to 6.1.3.

This commit is contained in:
Duncaen
2026-07-30 03:37:48 +02:00
parent b2ae3879ae
commit 2d9bd3b3ac
7 changed files with 302 additions and 110 deletions
@@ -0,0 +1,37 @@
From 212fd4a4ce1f89e8bbb6e6ab5a16053276234131 Mon Sep 17 00:00:00 2001
From: Anthony Hurtado <amhurtado@protonmail.com>
Date: Mon, 1 Jun 2026 15:40:48 -0500
Subject: [PATCH 1/3] Fix CVE-2026-26740: heap OOB write in
EGifGCBToSavedExtension
EGifGCBToSavedExtension calls EGifGCBToExtension which unconditionally
writes 4 bytes into ep->Bytes without checking ep->ByteCount. If the
extension block was allocated with fewer than 4 bytes, this results in
a heap buffer overflow.
The read-side counterpart DGifExtensionToGCB already validates that
GifExtensionLength == 4 before reading. Add the symmetric check on
the write side: return GIF_ERROR when ep->ByteCount < 4.
Signed-off-by: Anthony Hurtado <amhurtado@pm.me>
---
egif_lib.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/egif_lib.c b/egif_lib.c
index f1141a2..d74e8df 100644
--- a/egif_lib.c
+++ b/egif_lib.c
@@ -690,6 +690,9 @@ int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB,
ExtensionBlock *ep =
&GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
if (ep->Function == GRAPHICS_EXT_FUNC_CODE) {
+ if (ep->ByteCount < 4) {
+ return GIF_ERROR;
+ }
EGifGCBToExtension(GCB, ep->Bytes);
return GIF_OK;
}
--
2.55.0
@@ -0,0 +1,233 @@
From 9985cfa12c58bd0fd95fd782bd7018499b1e6d7f Mon Sep 17 00:00:00 2001
From: Anthony Hurtado <amhurtado@protonmail.com>
Date: Mon, 1 Jun 2026 15:41:11 -0500
Subject: [PATCH 2/3] Fix integer overflow and type safety issues across giflib
Multiple integer overflow vulnerabilities exist in giflib's pixel count
and dimension arithmetic. On 32-bit platforms where long and int are
32 bits, these overflow to negative values or wrap around, causing
heap buffer overflows, incorrect loop bounds, and undefined behavior.
dgif_lib.c:
- PixelCount: cast to (unsigned long) instead of signed (long) to
prevent signed overflow UB on 32-bit platforms.
- LZW CodeSize: reject BitsPerPixel < 2 (CodeSize 0 and 1 create
degenerate LZW states where ClearCode/EOFCode are unreachable).
egif_lib.c:
- PixelCount: same (unsigned long) fix as dgif_lib.c.
- EGifSpew: cast j to (size_t) in pointer arithmetic j * SavedWidth
to prevent int*int overflow in raster offset computation.
gifalloc.c:
- GifApplyTranslation: use size_t for RasterSize and loop counter
instead of int to prevent Height*Width overflow.
- GifMakeSavedImage: cast Height to (size_t) in reallocarray nmemb
and memcpy size to prevent int*int overflow before reaching
reallocarray's internal overflow check.
quantize.c:
- Compute PixelCount as (size_t)Width * Height with division-based
overflow guard. Use size_t loop counter for pixel iteration.
- Replace signed (long) cast of pixel count with (unsigned long).
All 51 regression tests pass. Compiles with zero warnings under
-Wall -O2.
Signed-off-by: Anthony Hurtado <amhurtado@pm.me>
---
dgif_lib.c | 5 +++--
egif_lib.c | 7 ++++---
gifalloc.c | 16 ++++++++--------
quantize.c | 39 +++++++++++++++++++++++----------------
4 files changed, 38 insertions(+), 29 deletions(-)
diff --git a/dgif_lib.c b/dgif_lib.c
index cec94c1..a022bb6 100644
--- a/dgif_lib.c
+++ b/dgif_lib.c
@@ -416,7 +416,8 @@ int DGifGetImageHeader(GifFileType *GifFile) {
}
Private->PixelCount =
- (long)GifFile->Image.Width * (long)GifFile->Image.Height;
+ (unsigned long)GifFile->Image.Width *
+ (unsigned long)GifFile->Image.Height;
/* Reset decompress algorithm parameters. */
return DGifSetupDecompress(GifFile);
@@ -824,7 +825,7 @@ static int DGifSetupDecompress(GifFileType *GifFile) {
BitsPerPixel = CodeSize;
/* this can only happen on a severely malformed GIF */
- if (BitsPerPixel > 8) {
+ if (BitsPerPixel < 2 || BitsPerPixel > 8) {
GifFile->Error =
D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
return GIF_ERROR; /* Failed to read Code size. */
diff --git a/egif_lib.c b/egif_lib.c
index d74e8df..6f7c9b6 100644
--- a/egif_lib.c
+++ b/egif_lib.c
@@ -448,7 +448,8 @@ int EGifPutImageDesc(GifFileType *GifFile, const int Left, const int Top,
/* Mark this file as has screen descriptor: */
Private->FileState |= FILE_STATE_IMAGE;
- Private->PixelCount = (long)Width * (long)Height;
+ Private->PixelCount =
+ (unsigned long)Width * (unsigned long)Height;
/* Reset compress algorithm parameters. */
(void)EGifSetupCompress(GifFile);
@@ -1154,7 +1155,7 @@ int EGifSpew(GifFileType *GifFileOut, int *ErrorCode) {
j += InterlacedJumps[k]) {
if (EGifPutLine(
GifFileOut,
- sp->RasterBits + j * SavedWidth,
+ sp->RasterBits + (size_t)j * SavedWidth,
SavedWidth) == GIF_ERROR) {
status = GIF_ERROR;
err = GifFileOut->Error;
@@ -1165,7 +1166,7 @@ int EGifSpew(GifFileType *GifFileOut, int *ErrorCode) {
} else {
for (j = 0; j < SavedHeight; j++) {
if (EGifPutLine(GifFileOut,
- sp->RasterBits + j * SavedWidth,
+ sp->RasterBits + (size_t)j * SavedWidth,
SavedWidth) == GIF_ERROR) {
status = GIF_ERROR;
err = GifFileOut->Error;
diff --git a/gifalloc.c b/gifalloc.c
index 3d897ab..886907d 100644
--- a/gifalloc.c
+++ b/gifalloc.c
@@ -210,9 +210,9 @@ ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
Apply a given color translation to the raster bits of an image
*******************************************************************************/
void GifApplyTranslation(SavedImage *Image, const GifPixelType Translation[]) {
- register int i;
- register int RasterSize =
- Image->ImageDesc.Height * Image->ImageDesc.Width;
+ size_t i;
+ size_t RasterSize =
+ (size_t)Image->ImageDesc.Height * Image->ImageDesc.Width;
for (i = 0; i < RasterSize; i++) {
Image->RasterBits[i] = Translation[Image->RasterBits[i]];
@@ -371,17 +371,17 @@ SavedImage *GifMakeSavedImage(GifFileType *GifFile,
/* next, the raster */
sp->RasterBits = (unsigned char *)reallocarray(
NULL,
- (CopyFrom->ImageDesc.Height *
- CopyFrom->ImageDesc.Width),
+ (size_t)CopyFrom->ImageDesc.Height *
+ CopyFrom->ImageDesc.Width,
sizeof(GifPixelType));
if (sp->RasterBits == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
memcpy(sp->RasterBits, CopyFrom->RasterBits,
- sizeof(GifPixelType) *
- CopyFrom->ImageDesc.Height *
- CopyFrom->ImageDesc.Width);
+ (size_t)CopyFrom->ImageDesc.Height *
+ CopyFrom->ImageDesc.Width *
+ sizeof(GifPixelType));
/* finally, the extension blocks */
if (CopyFrom->ExtensionBlocks != NULL) {
diff --git a/quantize.c b/quantize.c
index 160a29b..4ea44ce 100644
--- a/quantize.c
+++ b/quantize.c
@@ -71,6 +71,7 @@ int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
long Red, Green, Blue;
NewColorMapType NewColorSubdiv[256];
QuantizedColorType *ColorArrayEntries, *QuantizedColor;
+ size_t k, PixelCount;
ColorArrayEntries = (QuantizedColorType *)malloc(
sizeof(QuantizedColorType) * COLOR_ARRAY_SIZE);
@@ -78,6 +79,12 @@ int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
return GIF_ERROR;
}
+ PixelCount = (size_t)Width * Height;
+ if (Width != 0 && PixelCount / Width != Height) {
+ free((char *)ColorArrayEntries);
+ return GIF_ERROR;
+ }
+
for (i = 0; i < COLOR_ARRAY_SIZE; i++) {
ColorArrayEntries[i].RGB[0] = i >> (2 * BITS_PER_PRIM_COLOR);
ColorArrayEntries[i].RGB[1] =
@@ -87,12 +94,12 @@ int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
}
/* Sample the colors and their distribution: */
- for (i = 0; i < (int)(Width * Height); i++) {
- Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR))
+ for (k = 0; k < PixelCount; k++) {
+ Index = ((RedInput[k] >> (8 - BITS_PER_PRIM_COLOR))
<< (2 * BITS_PER_PRIM_COLOR)) +
- ((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR))
+ ((GreenInput[k] >> (8 - BITS_PER_PRIM_COLOR))
<< BITS_PER_PRIM_COLOR) +
- (BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR));
+ (BlueInput[k] >> (8 - BITS_PER_PRIM_COLOR));
ColorArrayEntries[Index].Count++;
}
@@ -127,7 +134,7 @@ int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
NewColorSubdiv[0].NumEntries =
NumOfEntries; /* Different sampled colors */
- NewColorSubdiv[0].Count = ((long)Width) * Height; /* Pixels */
+ NewColorSubdiv[0].Count = (unsigned long)PixelCount; /* Pixels */
NewColorMapSize = 1;
if (SubdivColorMap(NewColorSubdiv, *ColorMapSize, &NewColorMapSize) !=
GIF_OK) {
@@ -167,28 +174,28 @@ int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
/* Finally scan the input buffer again and put the mapped index in the
* output buffer. */
MaxRGBError[0] = MaxRGBError[1] = MaxRGBError[2] = 0;
- for (i = 0; i < (int)(Width * Height); i++) {
- Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR))
+ for (k = 0; k < PixelCount; k++) {
+ Index = ((RedInput[k] >> (8 - BITS_PER_PRIM_COLOR))
<< (2 * BITS_PER_PRIM_COLOR)) +
- ((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR))
+ ((GreenInput[k] >> (8 - BITS_PER_PRIM_COLOR))
<< BITS_PER_PRIM_COLOR) +
- (BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR));
+ (BlueInput[k] >> (8 - BITS_PER_PRIM_COLOR));
Index = ColorArrayEntries[Index].NewColorIndex;
- OutputBuffer[i] = Index;
+ OutputBuffer[k] = Index;
if (MaxRGBError[0] <
- ABS(OutputColorMap[Index].Red - RedInput[i])) {
+ ABS(OutputColorMap[Index].Red - RedInput[k])) {
MaxRGBError[0] =
- ABS(OutputColorMap[Index].Red - RedInput[i]);
+ ABS(OutputColorMap[Index].Red - RedInput[k]);
}
if (MaxRGBError[1] <
- ABS(OutputColorMap[Index].Green - GreenInput[i])) {
+ ABS(OutputColorMap[Index].Green - GreenInput[k])) {
MaxRGBError[1] =
- ABS(OutputColorMap[Index].Green - GreenInput[i]);
+ ABS(OutputColorMap[Index].Green - GreenInput[k]);
}
if (MaxRGBError[2] <
- ABS(OutputColorMap[Index].Blue - BlueInput[i])) {
+ ABS(OutputColorMap[Index].Blue - BlueInput[k])) {
MaxRGBError[2] =
- ABS(OutputColorMap[Index].Blue - BlueInput[i]);
+ ABS(OutputColorMap[Index].Blue - BlueInput[k]);
}
}
--
2.55.0
@@ -0,0 +1,28 @@
From 4a4fb2131c48b912b762a0c9915a2d717de7132a Mon Sep 17 00:00:00 2001
From: "Eric S. Raymond" <esr@thyrsus.com>
Date: Wed, 10 Jun 2026 17:00:29 -0400
Subject: [PATCH 3/3] Resolve ticket #203: GifUnionColorMap NULL Pointer
Dereference
---
gifalloc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/gifalloc.c b/gifalloc.c
index 886907d..e36684b 100644
--- a/gifalloc.c
+++ b/gifalloc.c
@@ -114,6 +114,10 @@ ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
ColorMapObject *ColorUnion;
+ if (ColorIn1 == NULL || ColorIn2 == NULL) {
+ return (NULL);
+ }
+
/*
* We don't worry about duplicates within either color map; if
* the caller wants to resolve those, he can perform unions
--
2.55.0
@@ -1,30 +0,0 @@
From ccbc956432650734c91acb3fc88837f7b81267ff Mon Sep 17 00:00:00 2001
From: "Eric S. Raymond" <esr@thyrsus.com>
Date: Wed, 21 Feb 2024 18:55:00 -0500
Subject: [PATCH] Clean up memory better at end of run (CVE-2021-40633)
---
gif2rgb.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/gif2rgb.c b/gif2rgb.c
index d51226d..fc2e683 100644
--- a/gif2rgb.c
+++ b/gif2rgb.c
@@ -515,10 +515,13 @@ static void GIF2RGB(int NumFiles, char *FileName, bool OneFileFlag,
}
DumpScreen2RGB(OutFileName, OneFileFlag, ColorMap, ScreenBuffer,
GifFile->SWidth, GifFile->SHeight);
+ for (i = 0; i < GifFile->SHeight; i++) {
+ (void)free(ScreenBuffer[i]);
+ }
(void)free(ScreenBuffer);
{
int Error;
if (DGifCloseFile(GifFile, &Error) == GIF_ERROR) {
--
2.43.0
@@ -1,58 +0,0 @@
From 61f375082c80ee479eb8ff03189aea691a6a06aa Mon Sep 17 00:00:00 2001
From: "Eric S. Raymond" <esr@thyrsus.com>
Date: Wed, 21 Feb 2024 08:33:51 -0500
Subject: [PATCH] Correct document page install.
---
Makefile | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile
index 87966a9..f4ecb24 100644
--- a/Makefile
+++ b/Makefile
@@ -61,19 +61,23 @@ UTILS = $(INSTALLABLE) \
gifsponge \
gifwedge
LDLIBS=libgif.a -lm
-MANUAL_PAGES = \
+MANUAL_PAGES_1 = \
doc/gif2rgb.xml \
doc/gifbuild.xml \
doc/gifclrmp.xml \
doc/giffix.xml \
- doc/giflib.xml \
doc/giftext.xml \
doc/giftool.xml
+MANUAL_PAGES_7 = \
+ doc/giflib.xml
+
+MANUAL_PAGES = $(MANUAL_PAGES_1) $(MANUAL_PAGES_7)
+
SOEXTENSION = so
LIBGIFSO = libgif.$(SOEXTENSION)
LIBGIFSOMAJOR = libgif.$(SOEXTENSION).$(LIBMAJOR)
LIBGIFSOVER = libgif.$(SOEXTENSION).$(LIBVER)
LIBUTILSO = libutil.$(SOEXTENSION)
@@ -146,12 +150,13 @@ install-lib:
$(INSTALL) -m 644 libgif.a "$(DESTDIR)$(LIBDIR)/libgif.a"
$(INSTALL) -m 755 $(LIBGIFSO) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSOVER)"
ln -sf $(LIBGIFSOVER) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSOMAJOR)"
ln -sf $(LIBGIFSOMAJOR) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSO)"
install-man:
- $(INSTALL) -d "$(DESTDIR)$(MANDIR)/man1"
- $(INSTALL) -m 644 $(MANUAL_PAGES) "$(DESTDIR)$(MANDIR)/man1"
+ $(INSTALL) -d "$(DESTDIR)$(MANDIR)/man1" "$(DESTDIR)$(MANDIR)/man7"
+ $(INSTALL) -m 644 $(MANUAL_PAGES_1:xml=1) "$(DESTDIR)$(MANDIR)/man1"
+ $(INSTALL) -m 644 $(MANUAL_PAGES_7:xml=7) "$(DESTDIR)$(MANDIR)/man7"
uninstall: uninstall-man uninstall-include uninstall-lib uninstall-bin
uninstall-bin:
cd "$(DESTDIR)$(BINDIR)" && rm -f $(INSTALLABLE)
uninstall-include:
rm -f "$(DESTDIR)$(INCDIR)/gif_lib.h"
--
2.43.0
@@ -1,19 +0,0 @@
Upstream: No
Reason: restores deprecated GifQuantizeBuffer which some packages (notably libgdiplus) still use
--- a/Makefile
+++ b/Makefile
@@ -95,11 +95,11 @@
$(UTILS):: libgif.a libutil.a
-$(LIBGIFSO): $(OBJECTS) $(HEADERS)
+$(LIBGIFSO): $(OBJECTS) $(HEADERS) $(UOBJECTS)
ifeq ($(UNAME), Darwin)
$(CC) $(CFLAGS) -dynamiclib -current_version $(LIBVER) $(OBJECTS) -o $(LIBGIFSO)
else
- $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,$(LIBGIFSOMAJOR) -o $(LIBGIFSO) $(OBJECTS)
+ $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,$(LIBGIFSOMAJOR) -o $(LIBGIFSO) $(OBJECTS) $(UOBJECTS)
endif
libgif.a: $(OBJECTS) $(HEADERS)
+4 -3
View File
@@ -1,21 +1,22 @@
# Template file for 'giflib'
pkgname=giflib
version=5.2.2
version=6.1.3
revision=1
build_style=gnu-makefile
make_check_target="test"
hostmakedepends="xmlto"
short_desc="Library to handle, display and manipulate GIF images"
maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="https://sourceforge.net/projects/giflib/"
distfiles="${SOURCEFORGE_SITE}/${pkgname}/${pkgname}-${version}.tar.gz"
checksum=be7ffbd057cadebe2aa144542fd90c6838c6a083b5e8a9048b8ee3b66b29d5fb
checksum=b65b66b99f0424b93525f987386f22fc5efb9da2bfc92ad4a532249aaffbab0e
CFLAGS="-fPIC"
post_patch() {
# don't build images for html doc, requires ImageMackig
vsed -i doc/Makefile -e '/^allhtml/s/giflib-logo.gif//'
vsed -i doc/Makefile -e '/^website/s/giflib-logo\.gif//'
}
post_install() {