/
gif_fix_image_counter.patch
89 lines (82 loc) · 3.68 KB
/
gif_fix_image_counter.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
diff --git a/dgif_lib.c b/dgif_lib.c
index 82fc097..214a0e7 100644
--- a/dgif_lib.c
+++ b/dgif_lib.c
@@ -810,7 +810,8 @@ DGifSetupDecompress(GifFileType *GifFile)
/* coverity[check_return] */
if (InternalRead(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */
- return GIF_ERROR; /* Failed to read Code size. */
+ GifFile->Error = D_GIF_ERR_READ_FAILED;
+ return GIF_ERROR; /* Failed to read Code size. */
}
BitsPerPixel = CodeSize;
@@ -1118,6 +1119,31 @@ DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
return GIF_OK;
}
+/******************************************************************************
+ This routine is called in case of error during parsing image. We need to
+ decrease image counter and reallocate memory for saved images. Not decreasing
+ ImageCount may lead to null pointer dereference, because the last element in
+ SavedImages may point to the spoilt image and null pointer buffers.
+*******************************************************************************/
+void
+DGifDecreaseImageCounter(GifFileType *GifFile)
+{
+ GifFile->ImageCount--;
+ if (GifFile->SavedImages[GifFile->ImageCount].RasterBits != NULL) {
+ free(GifFile->SavedImages[GifFile->ImageCount].RasterBits);
+ }
+ if (GifFile->SavedImages[GifFile->ImageCount].ImageDesc.ColorMap != NULL) {
+ GifFreeMapObject(GifFile->SavedImages[GifFile->ImageCount].ImageDesc.ColorMap);
+ }
+
+ // Realloc array according to the new image counter.
+ SavedImage *correct_saved_images = (SavedImage *)reallocarray(
+ GifFile->SavedImages, GifFile->ImageCount, sizeof(SavedImage));
+ if (correct_saved_images != NULL) {
+ GifFile->SavedImages = correct_saved_images;
+ }
+}
+
/******************************************************************************
This routine reads an entire GIF into core, hanging all its state info off
the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
@@ -1148,17 +1174,20 @@ DGifSlurp(GifFileType *GifFile)
/* Allocate memory for the image */
if (sp->ImageDesc.Width <= 0 || sp->ImageDesc.Height <= 0 ||
sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
+ DGifDecreaseImageCounter(GifFile);
return GIF_ERROR;
}
ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
+ DGifDecreaseImageCounter(GifFile);
return GIF_ERROR;
}
sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
sizeof(GifPixelType));
if (sp->RasterBits == NULL) {
+ DGifDecreaseImageCounter(GifFile);
return GIF_ERROR;
}
@@ -1177,13 +1206,17 @@ DGifSlurp(GifFileType *GifFile)
j += InterlacedJumps[i]) {
if (DGifGetLine(GifFile,
sp->RasterBits+j*sp->ImageDesc.Width,
- sp->ImageDesc.Width) == GIF_ERROR)
- return GIF_ERROR;
+ sp->ImageDesc.Width) == GIF_ERROR) {
+ DGifDecreaseImageCounter(GifFile);
+ return GIF_ERROR;
+ }
}
}
else {
- if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
- return (GIF_ERROR);
+ if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR) {
+ DGifDecreaseImageCounter(GifFile);
+ return GIF_ERROR;
+ }
}
if (GifFile->ExtensionBlocks) {