Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libgif/ORIGIN.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Files in this folder are based on giflib-5.0.0
Files in this folder are based on giflib-5.1.4

Original source archives are available from <http://giflib.sourceforge.net/>
Original source archives are available from <http://giflib.sourceforge.net/>
19 changes: 13 additions & 6 deletions libgif/include/gif_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ extern "C" {
#endif /* __cplusplus */

#define GIFLIB_MAJOR 5
#define GIFLIB_MINOR 0
#define GIFLIB_RELEASE 0
#define GIFLIB_MINOR 1
#define GIFLIB_RELEASE 4

#define GIF_ERROR 0
#define GIF_OK 1

#include <stddef.h>
#ifndef _WIN32
#include <stdbool.h>
#else
Expand Down Expand Up @@ -135,9 +136,10 @@ GifFileType *EGifOpenFileName(const char *GifFileName,
GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
int EGifSpew(GifFileType * GifFile);
char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */
int EGifCloseFile(GifFileType * GifFile);
const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */
int EGifCloseFile(GifFileType *GifFile, int *ErrorCode);

#define E_GIF_SUCCEEDED 0
#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
#define E_GIF_ERR_WRITE_FAILED 2
#define E_GIF_ERR_HAS_SCRN_DSCR 3
Expand All @@ -160,6 +162,7 @@ int EGifPutImageDesc(GifFileType *GifFile,
const int GifWidth, const int GifHeight,
const bool GifInterlace,
const ColorMapObject *GifColorMap);
void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
int GifLineLen);
int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
Expand All @@ -185,8 +188,9 @@ GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
int DGifSlurp(GifFileType * GifFile);
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error); /* new one (TVT) */
int DGifCloseFile(GifFileType * GifFile);
int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);

#define D_GIF_SUCCEEDED 0
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
Expand Down Expand Up @@ -229,7 +233,7 @@ int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
/******************************************************************************
Error handling and reporting.
******************************************************************************/
extern char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */

/*****************************************************************************
Everything below this point is new after version 1.2, supporting `slurp
Expand All @@ -248,6 +252,9 @@ extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
GifPixelType ColorTransIn2[]);
extern int GifBitSize(int n);

extern void *
reallocarray(void *optr, size_t nmemb, size_t size);

/******************************************************************************
Support for the in-core structures allocation (slurp mode).
******************************************************************************/
Expand Down
1 change: 1 addition & 0 deletions libgif/libgif.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
'src/gif_font.c',
'src/gif_hash.c',
'src/gifalloc.c',
'src/openbsd-reallocarray.c',
'src/quantize.c',
],

Expand Down
106 changes: 66 additions & 40 deletions libgif/src/dgif_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ DGifOpenFileName(const char *FileName, int *Error)
}

GifFile = DGifOpenFileHandle(FileHandle, Error);
// cppcheck-suppress resourceLeak
return GifFile;
}

Expand Down Expand Up @@ -93,14 +92,17 @@ DGifOpenFileHandle(int FileHandle, int *Error)
GifFile->SavedImages = NULL;
GifFile->SColorMap = NULL;

Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
if (Private == NULL) {
if (Error != NULL)
*Error = D_GIF_ERR_NOT_ENOUGH_MEM;
(void)close(FileHandle);
free((char *)GifFile);
return NULL;
}

/*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));

#ifdef _WIN32
_setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
#endif /* _WIN32 */
Expand All @@ -117,6 +119,7 @@ DGifOpenFileHandle(int FileHandle, int *Error)
/*@=mustfreeonly@*/

/* Let's see if this is a GIF file: */
/* coverity[check_return] */
if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
if (Error != NULL)
*Error = D_GIF_ERR_READ_FAILED;
Expand Down Expand Up @@ -175,13 +178,14 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
GifFile->SavedImages = NULL;
GifFile->SColorMap = NULL;

Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
if (!Private) {
if (Error != NULL)
*Error = D_GIF_ERR_NOT_ENOUGH_MEM;
free((char *)GifFile);
return NULL;
}
/*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));

GifFile->Private = (void *)Private;
Private->FileHandle = 0;
Expand All @@ -192,6 +196,7 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
GifFile->UserData = userData; /* TVT */

/* Lets see if this is a GIF file: */
/* coverity[check_return] */
if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
if (Error != NULL)
*Error = D_GIF_ERR_READ_FAILED;
Expand All @@ -213,6 +218,8 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
free((char *)Private);
free((char *)GifFile);
if (Error != NULL)
*Error = D_GIF_ERR_NO_SCRN_DSCR;
return NULL;
}

Expand Down Expand Up @@ -270,6 +277,7 @@ DGifGetScreenDesc(GifFileType *GifFile)
/* Get the global color map: */
GifFile->SColorMap->SortFlag = SortFlag;
for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
/* coverity[check_return] */
if (READ(GifFile, Buf, 3) != 3) {
GifFreeMapObject(GifFile->SColorMap);
GifFile->SColorMap = NULL;
Expand Down Expand Up @@ -302,6 +310,7 @@ DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
return GIF_ERROR;
}

/* coverity[check_return] */
if (READ(GifFile, &Buf, 1) != 1) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
Expand Down Expand Up @@ -375,6 +384,7 @@ DGifGetImageDesc(GifFileType *GifFile)

/* Get the image local color map: */
for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
/* coverity[check_return] */
if (READ(GifFile, Buf, 3) != 3) {
GifFreeMapObject(GifFile->Image.ColorMap);
GifFile->Error = D_GIF_ERR_READ_FAILED;
Expand All @@ -388,12 +398,14 @@ DGifGetImageDesc(GifFileType *GifFile)
}

if (GifFile->SavedImages) {
if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
sizeof(SavedImage) *
(GifFile->ImageCount + 1))) == NULL) {
SavedImage* new_saved_images =
(SavedImage *)reallocarray(GifFile->SavedImages,
(GifFile->ImageCount + 1), sizeof(SavedImage));
if (new_saved_images == NULL) {
GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
}
GifFile->SavedImages = new_saved_images;
} else {
if ((GifFile->SavedImages =
(SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
Expand Down Expand Up @@ -423,9 +435,7 @@ DGifGetImageDesc(GifFileType *GifFile)
(long)GifFile->Image.Height;

/* Reset decompress algorithm parameters. */
(void)DGifSetupDecompress(GifFile);

return GIF_OK;
return DGifSetupDecompress(GifFile);
}

/******************************************************************************
Expand Down Expand Up @@ -524,6 +534,7 @@ DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
return GIF_ERROR;
}

/* coverity[check_return] */
if (READ(GifFile, &Buf, 1) != 1) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
Expand Down Expand Up @@ -551,7 +562,7 @@ DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
if (Buf > 0) {
*Extension = Private->Buf; /* Use private unused buffer. */
(*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
/* coverity[tainted_data] */
/* coverity[tainted_data,check_return] */
if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
Expand Down Expand Up @@ -615,7 +626,7 @@ int DGifSavedExtensionToGCB(GifFileType *GifFile,
This routine should be called last, to close the GIF file.
******************************************************************************/
int
DGifCloseFile(GifFileType *GifFile)
DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
{
GifFilePrivateType *Private;

Expand Down Expand Up @@ -643,25 +654,25 @@ DGifCloseFile(GifFileType *GifFile)

if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
GifFile->Error = D_GIF_ERR_NOT_READABLE;
if (ErrorCode != NULL)
*ErrorCode = D_GIF_ERR_NOT_READABLE;
free((char *)GifFile->Private);
free(GifFile);
return GIF_ERROR;
}

if (Private->File && (fclose(Private->File) != 0)) {
GifFile->Error = D_GIF_ERR_CLOSE_FAILED;
if (ErrorCode != NULL)
*ErrorCode = D_GIF_ERR_CLOSE_FAILED;
free((char *)GifFile->Private);
free(GifFile);
return GIF_ERROR;
}

free((char *)GifFile->Private);

/*
* Without the #ifndef, we get spurious warnings because Coverity mistakenly
* thinks the GIF structure is freed on an error return.
*/
#ifndef __COVERITY__
free(GifFile);
#endif /* __COVERITY__ */

if (ErrorCode != NULL)
*ErrorCode = D_GIF_SUCCEEDED;
return GIF_OK;
}

Expand All @@ -673,6 +684,7 @@ DGifGetWord(GifFileType *GifFile, GifWord *Word)
{
unsigned char c[2];

/* coverity[check_return] */
if (READ(GifFile, c, 2) != 2) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
Expand Down Expand Up @@ -717,6 +729,7 @@ DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;

/* coverity[tainted_data_argument] */
/* coverity[check_return] */
if (READ(GifFile, &Buf, 1) != 1) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
Expand Down Expand Up @@ -751,9 +764,18 @@ DGifSetupDecompress(GifFileType *GifFile)
GifPrefixType *Prefix;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;

READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
/* coverity[check_return] */
if (READ(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */
return GIF_ERROR; /* Failed to read Code size. */
}
BitsPerPixel = CodeSize;

/* this can only happen on a severely malformed GIF */
if (BitsPerPixel > 8) {
GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
return GIF_ERROR; /* Failed to read Code size. */
}

Private->Buf[0] = 0; /* Input Buffer empty. */
Private->BitsPerPixel = BitsPerPixel;
Private->ClearCode = (1 << BitsPerPixel);
Expand Down Expand Up @@ -837,19 +859,22 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
* pixels on our stack. If we done, pop the stack in reverse
* (thats what stack is good for!) order to output. */
if (Prefix[CrntCode] == NO_SUCH_CODE) {
CrntPrefix = LastCode;

/* Only allowed if CrntCode is exactly the running code:
* In that case CrntCode = XXXCode, CrntCode or the
* prefix code is last code and the suffix char is
* exactly the prefix of last code! */
if (CrntCode == Private->RunningCode - 2) {
CrntPrefix = LastCode;
Suffix[Private->RunningCode - 2] =
Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
LastCode,
ClearCode);
} else {
GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
return GIF_ERROR;
Suffix[Private->RunningCode - 2] =
Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
CrntCode,
ClearCode);
}
} else
CrntPrefix = CrntCode;
Expand All @@ -874,7 +899,7 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
while (StackPtr != 0 && i < LineLen)
Line[i++] = Stack[--StackPtr];
}
if (LastCode != NO_SUCH_CODE) {
if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
Prefix[Private->RunningCode - 2] = LastCode;

if (CrntCode == Private->RunningCode - 2) {
Expand Down Expand Up @@ -1021,6 +1046,7 @@ DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
{
if (Buf[0] == 0) {
/* Needs to read the next buffer - this one is empty: */
/* coverity[check_return] */
if (READ(GifFile, Buf, 1) != 1) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
Expand All @@ -1033,14 +1059,6 @@ DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
return GIF_ERROR;
}
/* There shouldn't be any empty data blocks here as the LZW spec
* says the LZW termination code should come first. Therefore we
* shouldn't be inside this routine at that point.
*/
if (Buf[0] == 0) {
GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
return GIF_ERROR;
}
if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
GifFile->Error = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
Expand Down Expand Up @@ -1093,7 +1111,7 @@ DGifSlurp(GifFileType *GifFile)
if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
return GIF_ERROR;
}
sp->RasterBits = (unsigned char *)malloc(ImageSize *
sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
sizeof(GifPixelType));

if (sp->RasterBits == NULL) {
Expand Down Expand Up @@ -1137,11 +1155,13 @@ DGifSlurp(GifFileType *GifFile)
if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
return (GIF_ERROR);
/* Create an extension block with our data */
if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
&GifFile->ExtensionBlocks,
ExtFunction, ExtData[0], &ExtData[1])
== GIF_ERROR)
return (GIF_ERROR);
if (ExtData != NULL) {
if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
&GifFile->ExtensionBlocks,
ExtFunction, ExtData[0], &ExtData[1])
== GIF_ERROR)
return (GIF_ERROR);
}
while (ExtData != NULL) {
if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
return (GIF_ERROR);
Expand All @@ -1163,6 +1183,12 @@ DGifSlurp(GifFileType *GifFile)
}
} while (RecordType != TERMINATE_RECORD_TYPE);

/* Sanity check for corrupted file */
if (GifFile->ImageCount == 0) {
GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
return(GIF_ERROR);
}

return (GIF_OK);
}

Expand Down
Loading