summaryrefslogtreecommitdiff
path: root/dgif_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'dgif_lib.c')
-rw-r--r--dgif_lib.c104
1 files changed, 64 insertions, 40 deletions
diff --git a/dgif_lib.c b/dgif_lib.c
index 744a2f9..66a1d6a 100644
--- a/dgif_lib.c
+++ b/dgif_lib.c
@@ -59,7 +59,6 @@ DGifOpenFileName(const char *FileName, int *Error)
}
GifFile = DGifOpenFileHandle(FileHandle, Error);
- // cppcheck-suppress resourceLeak
return GifFile;
}
@@ -90,7 +89,7 @@ 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;
@@ -98,6 +97,9 @@ DGifOpenFileHandle(int FileHandle, int *Error)
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 */
@@ -114,6 +116,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;
@@ -172,13 +175,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;
@@ -189,6 +193,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;
@@ -210,6 +215,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;
}
@@ -267,6 +274,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;
@@ -299,6 +307,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;
@@ -372,6 +381,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;
@@ -385,12 +395,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) {
@@ -420,9 +432,7 @@ DGifGetImageDesc(GifFileType *GifFile)
(long)GifFile->Image.Height;
/* Reset decompress algorithm parameters. */
- (void)DGifSetupDecompress(GifFile);
-
- return GIF_OK;
+ return DGifSetupDecompress(GifFile);
}
/******************************************************************************
@@ -521,6 +531,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;
@@ -548,7 +559,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;
@@ -612,7 +623,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;
@@ -640,25 +651,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;
}
@@ -670,6 +681,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;
@@ -714,6 +726,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;
@@ -748,9 +761,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);
@@ -834,19 +856,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;
@@ -1018,6 +1043,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;
@@ -1030,14 +1056,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;
@@ -1090,7 +1108,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) {
@@ -1135,12 +1153,12 @@ DGifSlurp(GifFileType *GifFile)
return (GIF_ERROR);
/* Create an extension block with our data */
if (ExtData != NULL) {
- if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
- &GifFile->ExtensionBlocks,
- ExtFunction, ExtData[0], &ExtData[1])
- == GIF_ERROR)
- return (GIF_ERROR);
- }
+ 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);
@@ -1162,6 +1180,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);
}