@@ -62,7 +62,6 @@ DGifOpenFileName(const char *FileName, int *Error)
6262 }
6363
6464 GifFile = DGifOpenFileHandle (FileHandle , Error );
65- // cppcheck-suppress resourceLeak
6665 return GifFile ;
6766}
6867
@@ -93,14 +92,17 @@ DGifOpenFileHandle(int FileHandle, int *Error)
9392 GifFile -> SavedImages = NULL ;
9493 GifFile -> SColorMap = NULL ;
9594
96- Private = (GifFilePrivateType * )malloc ( sizeof (GifFilePrivateType ));
95+ Private = (GifFilePrivateType * )calloc ( 1 , sizeof (GifFilePrivateType ));
9796 if (Private == NULL ) {
9897 if (Error != NULL )
9998 * Error = D_GIF_ERR_NOT_ENOUGH_MEM ;
10099 (void )close (FileHandle );
101100 free ((char * )GifFile );
102101 return NULL ;
103102 }
103+
104+ /*@i1@*/ memset (Private , '\0' , sizeof (GifFilePrivateType ));
105+
104106#ifdef _WIN32
105107 _setmode (FileHandle , O_BINARY ); /* Make sure it is in binary mode. */
106108#endif /* _WIN32 */
@@ -117,6 +119,7 @@ DGifOpenFileHandle(int FileHandle, int *Error)
117119 /*@=mustfreeonly@*/
118120
119121 /* Let's see if this is a GIF file: */
122+ /* coverity[check_return] */
120123 if (READ (GifFile , (unsigned char * )Buf , GIF_STAMP_LEN ) != GIF_STAMP_LEN ) {
121124 if (Error != NULL )
122125 * Error = D_GIF_ERR_READ_FAILED ;
@@ -175,13 +178,14 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
175178 GifFile -> SavedImages = NULL ;
176179 GifFile -> SColorMap = NULL ;
177180
178- Private = (GifFilePrivateType * )malloc ( sizeof (GifFilePrivateType ));
181+ Private = (GifFilePrivateType * )calloc ( 1 , sizeof (GifFilePrivateType ));
179182 if (!Private ) {
180183 if (Error != NULL )
181184 * Error = D_GIF_ERR_NOT_ENOUGH_MEM ;
182185 free ((char * )GifFile );
183186 return NULL ;
184187 }
188+ /*@i1@*/ memset (Private , '\0' , sizeof (GifFilePrivateType ));
185189
186190 GifFile -> Private = (void * )Private ;
187191 Private -> FileHandle = 0 ;
@@ -192,6 +196,7 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
192196 GifFile -> UserData = userData ; /* TVT */
193197
194198 /* Lets see if this is a GIF file: */
199+ /* coverity[check_return] */
195200 if (READ (GifFile , (unsigned char * )Buf , GIF_STAMP_LEN ) != GIF_STAMP_LEN ) {
196201 if (Error != NULL )
197202 * Error = D_GIF_ERR_READ_FAILED ;
@@ -213,6 +218,8 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
213218 if (DGifGetScreenDesc (GifFile ) == GIF_ERROR ) {
214219 free ((char * )Private );
215220 free ((char * )GifFile );
221+ if (Error != NULL )
222+ * Error = D_GIF_ERR_NO_SCRN_DSCR ;
216223 return NULL ;
217224 }
218225
@@ -270,6 +277,7 @@ DGifGetScreenDesc(GifFileType *GifFile)
270277 /* Get the global color map: */
271278 GifFile -> SColorMap -> SortFlag = SortFlag ;
272279 for (i = 0 ; i < GifFile -> SColorMap -> ColorCount ; i ++ ) {
280+ /* coverity[check_return] */
273281 if (READ (GifFile , Buf , 3 ) != 3 ) {
274282 GifFreeMapObject (GifFile -> SColorMap );
275283 GifFile -> SColorMap = NULL ;
@@ -302,6 +310,7 @@ DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
302310 return GIF_ERROR ;
303311 }
304312
313+ /* coverity[check_return] */
305314 if (READ (GifFile , & Buf , 1 ) != 1 ) {
306315 GifFile -> Error = D_GIF_ERR_READ_FAILED ;
307316 return GIF_ERROR ;
@@ -375,6 +384,7 @@ DGifGetImageDesc(GifFileType *GifFile)
375384
376385 /* Get the image local color map: */
377386 for (i = 0 ; i < GifFile -> Image .ColorMap -> ColorCount ; i ++ ) {
387+ /* coverity[check_return] */
378388 if (READ (GifFile , Buf , 3 ) != 3 ) {
379389 GifFreeMapObject (GifFile -> Image .ColorMap );
380390 GifFile -> Error = D_GIF_ERR_READ_FAILED ;
@@ -388,12 +398,14 @@ DGifGetImageDesc(GifFileType *GifFile)
388398 }
389399
390400 if (GifFile -> SavedImages ) {
391- if ((GifFile -> SavedImages = (SavedImage * )realloc (GifFile -> SavedImages ,
392- sizeof (SavedImage ) *
393- (GifFile -> ImageCount + 1 ))) == NULL ) {
401+ SavedImage * new_saved_images =
402+ (SavedImage * )reallocarray (GifFile -> SavedImages ,
403+ (GifFile -> ImageCount + 1 ), sizeof (SavedImage ));
404+ if (new_saved_images == NULL ) {
394405 GifFile -> Error = D_GIF_ERR_NOT_ENOUGH_MEM ;
395406 return GIF_ERROR ;
396407 }
408+ GifFile -> SavedImages = new_saved_images ;
397409 } else {
398410 if ((GifFile -> SavedImages =
399411 (SavedImage * ) malloc (sizeof (SavedImage ))) == NULL ) {
@@ -423,9 +435,7 @@ DGifGetImageDesc(GifFileType *GifFile)
423435 (long )GifFile -> Image .Height ;
424436
425437 /* Reset decompress algorithm parameters. */
426- (void )DGifSetupDecompress (GifFile );
427-
428- return GIF_OK ;
438+ return DGifSetupDecompress (GifFile );
429439}
430440
431441/******************************************************************************
@@ -524,6 +534,7 @@ DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
524534 return GIF_ERROR ;
525535 }
526536
537+ /* coverity[check_return] */
527538 if (READ (GifFile , & Buf , 1 ) != 1 ) {
528539 GifFile -> Error = D_GIF_ERR_READ_FAILED ;
529540 return GIF_ERROR ;
@@ -551,7 +562,7 @@ DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
551562 if (Buf > 0 ) {
552563 * Extension = Private -> Buf ; /* Use private unused buffer. */
553564 (* Extension )[0 ] = Buf ; /* Pascal strings notation (pos. 0 is len.). */
554- /* coverity[tainted_data] */
565+ /* coverity[tainted_data,check_return ] */
555566 if (READ (GifFile , & ((* Extension )[1 ]), Buf ) != Buf ) {
556567 GifFile -> Error = D_GIF_ERR_READ_FAILED ;
557568 return GIF_ERROR ;
@@ -615,7 +626,7 @@ int DGifSavedExtensionToGCB(GifFileType *GifFile,
615626 This routine should be called last, to close the GIF file.
616627******************************************************************************/
617628int
618- DGifCloseFile (GifFileType * GifFile )
629+ DGifCloseFile (GifFileType * GifFile , int * ErrorCode )
619630{
620631 GifFilePrivateType * Private ;
621632
@@ -643,25 +654,25 @@ DGifCloseFile(GifFileType *GifFile)
643654
644655 if (!IS_READABLE (Private )) {
645656 /* This file was NOT open for reading: */
646- GifFile -> Error = D_GIF_ERR_NOT_READABLE ;
657+ if (ErrorCode != NULL )
658+ * ErrorCode = D_GIF_ERR_NOT_READABLE ;
659+ free ((char * )GifFile -> Private );
660+ free (GifFile );
647661 return GIF_ERROR ;
648662 }
649663
650664 if (Private -> File && (fclose (Private -> File ) != 0 )) {
651- GifFile -> Error = D_GIF_ERR_CLOSE_FAILED ;
665+ if (ErrorCode != NULL )
666+ * ErrorCode = D_GIF_ERR_CLOSE_FAILED ;
667+ free ((char * )GifFile -> Private );
668+ free (GifFile );
652669 return GIF_ERROR ;
653670 }
654671
655672 free ((char * )GifFile -> Private );
656-
657- /*
658- * Without the #ifndef, we get spurious warnings because Coverity mistakenly
659- * thinks the GIF structure is freed on an error return.
660- */
661- #ifndef __COVERITY__
662673 free (GifFile );
663- #endif /* __COVERITY__ */
664-
674+ if ( ErrorCode != NULL )
675+ * ErrorCode = D_GIF_SUCCEEDED ;
665676 return GIF_OK ;
666677}
667678
@@ -673,6 +684,7 @@ DGifGetWord(GifFileType *GifFile, GifWord *Word)
673684{
674685 unsigned char c [2 ];
675686
687+ /* coverity[check_return] */
676688 if (READ (GifFile , c , 2 ) != 2 ) {
677689 GifFile -> Error = D_GIF_ERR_READ_FAILED ;
678690 return GIF_ERROR ;
@@ -717,6 +729,7 @@ DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
717729 GifFilePrivateType * Private = (GifFilePrivateType * )GifFile -> Private ;
718730
719731 /* coverity[tainted_data_argument] */
732+ /* coverity[check_return] */
720733 if (READ (GifFile , & Buf , 1 ) != 1 ) {
721734 GifFile -> Error = D_GIF_ERR_READ_FAILED ;
722735 return GIF_ERROR ;
@@ -751,9 +764,18 @@ DGifSetupDecompress(GifFileType *GifFile)
751764 GifPrefixType * Prefix ;
752765 GifFilePrivateType * Private = (GifFilePrivateType * )GifFile -> Private ;
753766
754- READ (GifFile , & CodeSize , 1 ); /* Read Code size from file. */
767+ /* coverity[check_return] */
768+ if (READ (GifFile , & CodeSize , 1 ) < 1 ) { /* Read Code size from file. */
769+ return GIF_ERROR ; /* Failed to read Code size. */
770+ }
755771 BitsPerPixel = CodeSize ;
756772
773+ /* this can only happen on a severely malformed GIF */
774+ if (BitsPerPixel > 8 ) {
775+ GifFile -> Error = D_GIF_ERR_READ_FAILED ; /* somewhat bogus error code */
776+ return GIF_ERROR ; /* Failed to read Code size. */
777+ }
778+
757779 Private -> Buf [0 ] = 0 ; /* Input Buffer empty. */
758780 Private -> BitsPerPixel = BitsPerPixel ;
759781 Private -> ClearCode = (1 << BitsPerPixel );
@@ -837,19 +859,22 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
837859 * pixels on our stack. If we done, pop the stack in reverse
838860 * (thats what stack is good for!) order to output. */
839861 if (Prefix [CrntCode ] == NO_SUCH_CODE ) {
862+ CrntPrefix = LastCode ;
863+
840864 /* Only allowed if CrntCode is exactly the running code:
841865 * In that case CrntCode = XXXCode, CrntCode or the
842866 * prefix code is last code and the suffix char is
843867 * exactly the prefix of last code! */
844868 if (CrntCode == Private -> RunningCode - 2 ) {
845- CrntPrefix = LastCode ;
846869 Suffix [Private -> RunningCode - 2 ] =
847870 Stack [StackPtr ++ ] = DGifGetPrefixChar (Prefix ,
848871 LastCode ,
849872 ClearCode );
850873 } else {
851- GifFile -> Error = D_GIF_ERR_IMAGE_DEFECT ;
852- return GIF_ERROR ;
874+ Suffix [Private -> RunningCode - 2 ] =
875+ Stack [StackPtr ++ ] = DGifGetPrefixChar (Prefix ,
876+ CrntCode ,
877+ ClearCode );
853878 }
854879 } else
855880 CrntPrefix = CrntCode ;
@@ -874,7 +899,7 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
874899 while (StackPtr != 0 && i < LineLen )
875900 Line [i ++ ] = Stack [-- StackPtr ];
876901 }
877- if (LastCode != NO_SUCH_CODE ) {
902+ if (LastCode != NO_SUCH_CODE && Prefix [ Private -> RunningCode - 2 ] == NO_SUCH_CODE ) {
878903 Prefix [Private -> RunningCode - 2 ] = LastCode ;
879904
880905 if (CrntCode == Private -> RunningCode - 2 ) {
@@ -1021,6 +1046,7 @@ DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
10211046{
10221047 if (Buf [0 ] == 0 ) {
10231048 /* Needs to read the next buffer - this one is empty: */
1049+ /* coverity[check_return] */
10241050 if (READ (GifFile , Buf , 1 ) != 1 ) {
10251051 GifFile -> Error = D_GIF_ERR_READ_FAILED ;
10261052 return GIF_ERROR ;
@@ -1033,14 +1059,6 @@ DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
10331059 GifFile -> Error = D_GIF_ERR_IMAGE_DEFECT ;
10341060 return GIF_ERROR ;
10351061 }
1036- /* There shouldn't be any empty data blocks here as the LZW spec
1037- * says the LZW termination code should come first. Therefore we
1038- * shouldn't be inside this routine at that point.
1039- */
1040- if (Buf [0 ] == 0 ) {
1041- GifFile -> Error = D_GIF_ERR_IMAGE_DEFECT ;
1042- return GIF_ERROR ;
1043- }
10441062 if (READ (GifFile , & Buf [1 ], Buf [0 ]) != Buf [0 ]) {
10451063 GifFile -> Error = D_GIF_ERR_READ_FAILED ;
10461064 return GIF_ERROR ;
@@ -1093,7 +1111,7 @@ DGifSlurp(GifFileType *GifFile)
10931111 if (ImageSize > (SIZE_MAX / sizeof (GifPixelType ))) {
10941112 return GIF_ERROR ;
10951113 }
1096- sp -> RasterBits = (unsigned char * )malloc ( ImageSize *
1114+ sp -> RasterBits = (unsigned char * )reallocarray ( NULL , ImageSize ,
10971115 sizeof (GifPixelType ));
10981116
10991117 if (sp -> RasterBits == NULL ) {
@@ -1137,11 +1155,13 @@ DGifSlurp(GifFileType *GifFile)
11371155 if (DGifGetExtension (GifFile ,& ExtFunction ,& ExtData ) == GIF_ERROR )
11381156 return (GIF_ERROR );
11391157 /* Create an extension block with our data */
1140- if (GifAddExtensionBlock (& GifFile -> ExtensionBlockCount ,
1141- & GifFile -> ExtensionBlocks ,
1142- ExtFunction , ExtData [0 ], & ExtData [1 ])
1143- == GIF_ERROR )
1144- return (GIF_ERROR );
1158+ if (ExtData != NULL ) {
1159+ if (GifAddExtensionBlock (& GifFile -> ExtensionBlockCount ,
1160+ & GifFile -> ExtensionBlocks ,
1161+ ExtFunction , ExtData [0 ], & ExtData [1 ])
1162+ == GIF_ERROR )
1163+ return (GIF_ERROR );
1164+ }
11451165 while (ExtData != NULL ) {
11461166 if (DGifGetExtensionNext (GifFile , & ExtData ) == GIF_ERROR )
11471167 return (GIF_ERROR );
@@ -1163,6 +1183,12 @@ DGifSlurp(GifFileType *GifFile)
11631183 }
11641184 } while (RecordType != TERMINATE_RECORD_TYPE );
11651185
1186+ /* Sanity check for corrupted file */
1187+ if (GifFile -> ImageCount == 0 ) {
1188+ GifFile -> Error = D_GIF_ERR_NO_IMAG_DSCR ;
1189+ return (GIF_ERROR );
1190+ }
1191+
11661192 return (GIF_OK );
11671193}
11681194
0 commit comments