Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | #include "dgif_fuzz_common.h"  | 
2  |  | #include <iostream>  | 
3  |  |  | 
4  |  | using namespace std;  | 
5  |  |  | 
6  |  | extern "C" void PrintGifError(int ErrorCode);  | 
7  |  |  | 
8  |  | int stub_input_reader(GifFileType *gifFileType, GifByteType *gifByteType, int len)  | 
9  | 468k  | { | 
10  | 468k  |   struct gifUserData *gud = (struct gifUserData *)gifFileType->UserData;  | 
11  | 468k  |   if (gud->gifLen == 0)  | 
12  | 207  |     return 0;  | 
13  | 468k  |   int read_len = (len > gud->gifLen ? gud->gifLen : len);  | 
14  | 468k  |   memcpy(gifByteType, gud->gifData, read_len);  | 
15  | 468k  |   gud->gifData += read_len;  | 
16  | 468k  |   gud->gifLen -= read_len;  | 
17  | 468k  |   return read_len;  | 
18  | 468k  | }  | 
19  |  |  | 
20  |  | int fuzz_dgif(const uint8_t *Data, size_t Size)  | 
21  | 0  | { | 
22  | 0  |   GifFileType *GifFile;  | 
23  | 0  |   int Error;  | 
24  | 0  |   uint8_t *gifData = (uint8_t *)malloc(Size);  | 
25  | 0  |   memcpy(gifData, Data, Size);  | 
26  | 0  |   struct gifUserData gUData = {Size, gifData}; | 
27  |  | 
  | 
28  | 0  |   GifFile = DGifOpen((void *)&gUData, stub_input_reader, &Error);  | 
29  | 0  |   if (GifFile != NULL)  | 
30  | 0  |   { | 
31  | 0  |     DGifSlurp(GifFile);  | 
32  | 0  |     DGifCloseFile(GifFile, &Error);  | 
33  | 0  |   }  | 
34  | 0  |   free(gifData);  | 
35  | 0  |   return 0;  | 
36  | 0  | }  | 
37  |  |  | 
38  |  | int fuzz_dgif_extended(const uint8_t *Data, size_t Size)  | 
39  | 960  | { | 
40  | 960  |   GifFileType *GifFile;  | 
41  | 960  |   int Error;  | 
42  | 960  |   uint8_t *gifData = (uint8_t *)malloc(Size);  | 
43  | 960  |   memcpy(gifData, Data, Size);  | 
44  | 960  |   struct gifUserData gUData = {Size, gifData}; | 
45  |  |  | 
46  | 960  |   GifFile = DGifOpen((void *)&gUData, stub_input_reader, &Error);  | 
47  | 960  |   if (GifFile == NULL)  | 
48  | 18  |   { | 
49  | 18  |     free(gifData);  | 
50  | 18  |     return 0;  | 
51  | 18  |   }  | 
52  | 942  |   if (DGifSlurp(GifFile) != GIF_OK)  | 
53  | 825  |   { | 
54  | 825  |     DGifCloseFile(GifFile, &Error);  | 
55  | 825  |     free(gifData);  | 
56  | 825  |     return 0;  | 
57  | 825  |   }  | 
58  | 117  |   GraphicsControlBlock gcb;  | 
59  | 34.2k  |   for (int i = 0; i < GifFile->ImageCount; i++)  | 
60  | 34.1k  |   { | 
61  | 34.1k  |     DGifSavedExtensionToGCB(GifFile, i, &gcb);  | 
62  | 34.1k  |   }  | 
63  | 117  |   const ColorMapObject *cmap = GifFile->SColorMap;  | 
64  | 117  |   if (cmap)  | 
65  | 16  |   { | 
66  | 16  |     DGifSavedExtensionToGCB(GifFile, 0, &gcb);  | 
67  | 16  |   }  | 
68  | 117  |   DGifCloseFile(GifFile, &Error);  | 
69  | 117  |   free(gifData);  | 
70  | 117  |   return 0;  | 
71  | 942  | }  | 
72  |  |  | 
73  |  | static Color8888 gifColorToColor8888(const GifColorType &color)  | 
74  | 0  | { | 
75  | 0  |   return ARGB_TO_COLOR8888(0xff, color.Red, color.Green, color.Blue);  | 
76  | 0  | }  | 
77  |  |  | 
78  |  | static bool willBeCleared(const GraphicsControlBlock &gcb)  | 
79  | 0  | { | 
80  | 0  |   return gcb.DisposalMode == DISPOSE_BACKGROUND || gcb.DisposalMode == DISPOSE_PREVIOUS;  | 
81  | 0  | }  | 
82  |  |  | 
83  |  | static long getDelayMs(GraphicsControlBlock &gcb)  | 
84  | 0  | { | 
85  | 0  |   return gcb.DelayTime * 10;  | 
86  | 0  | }  | 
87  |  |  | 
88  |  | int fuzz_dgif_ala_android(const uint8_t *Data, size_t Size)  | 
89  | 0  | { | 
90  | 0  |   GifFileType *GifFile;  | 
91  | 0  |   int Error;  | 
92  | 0  |   uint8_t *gifData = (uint8_t *)malloc(Size);  | 
93  | 0  |   memcpy(gifData, Data, Size);  | 
94  | 0  |   struct gifUserData gUData = {Size, gifData}; | 
95  |  | 
  | 
96  | 0  |   GifFile = DGifOpen((void *)&gUData, stub_input_reader, &Error);  | 
97  | 0  |   if (GifFile == NULL)  | 
98  | 0  |   { | 
99  | 0  |     free(gifData);  | 
100  | 0  |     return 0;  | 
101  | 0  |   }  | 
102  |  |  | 
103  | 0  |   if (DGifSlurp(GifFile) != GIF_OK)  | 
104  | 0  |   { | 
105  | 0  |     PrintGifError(GifFile->Error);  | 
106  | 0  |     DGifCloseFile(GifFile, &Error);  | 
107  | 0  |     free(gifData);  | 
108  | 0  |     return 0;  | 
109  | 0  |   }  | 
110  |  |  | 
111  | 0  |   long durationMs = 0;  | 
112  | 0  |   int lastUnclearedFrame = -1;  | 
113  | 0  |   bool *preservedFrames = new bool[GifFile->ImageCount];  | 
114  | 0  |   int *restoringFrames = new int[GifFile->ImageCount];  | 
115  | 0  |   int loopCount = 0;  | 
116  | 0  |   Color8888 bgColor = 0;  | 
117  |  | 
  | 
118  | 0  |   GraphicsControlBlock gcb;  | 
119  | 0  |   for (int i = 0; i < GifFile->ImageCount; i++)  | 
120  | 0  |   { | 
121  | 0  |     const SavedImage &image = GifFile->SavedImages[i];  | 
122  |  |     // find the loop extension pair  | 
123  | 0  |     for (int j = 0; (j + 1) < image.ExtensionBlockCount; j++)  | 
124  | 0  |     { | 
125  | 0  |       ExtensionBlock *eb1 = image.ExtensionBlocks + j;  | 
126  | 0  |       ExtensionBlock *eb2 = image.ExtensionBlocks + j + 1;  | 
127  | 0  |       if (eb1->Function == APPLICATION_EXT_FUNC_CODE  | 
128  |  |         // look for "NETSCAPE2.0" app extension  | 
129  | 0  |         && eb1->ByteCount == 11 && !memcmp((const char *)(eb1->Bytes), "NETSCAPE2.0", 11)  | 
130  |  |         // verify extension contents and get loop count  | 
131  | 0  |         && eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount == 3 && eb2->Bytes[0] == 1)  | 
132  | 0  |       { | 
133  | 0  |         loopCount = (int)(eb2->Bytes[2] << 8) + (int)(eb2->Bytes[1]);  | 
134  | 0  |       }  | 
135  | 0  |     }  | 
136  | 0  |     DGifSavedExtensionToGCB(GifFile, i, &gcb);  | 
137  |  |     // timing  | 
138  | 0  |     durationMs += getDelayMs(gcb);  | 
139  |  |     // preserve logic  | 
140  | 0  |     preservedFrames[i] = false;  | 
141  | 0  |     restoringFrames[i] = -1;  | 
142  | 0  |     if (gcb.DisposalMode == DISPOSE_PREVIOUS && lastUnclearedFrame >= 0)  | 
143  | 0  |     { | 
144  | 0  |       preservedFrames[lastUnclearedFrame] = true;  | 
145  | 0  |       restoringFrames[i] = lastUnclearedFrame;  | 
146  | 0  |     }  | 
147  | 0  |     if (!willBeCleared(gcb))  | 
148  | 0  |     { | 
149  | 0  |       lastUnclearedFrame = i;  | 
150  | 0  |     }  | 
151  |  |     // Draw  | 
152  |  |     // assert(y+8 <= Image->ImageDesc.Height);  | 
153  |  |     // assert(x+8*strlen(legend) <= Image->ImageDesc.Width);  | 
154  | 0  |     int imgHeight = GifFile->SavedImages[i].ImageDesc.Height;  | 
155  | 0  |     int imgWidth = GifFile->SavedImages[i].ImageDesc.Width;  | 
156  |  |     // TODO: Source x,y, string, and color from fuzzer input  | 
157  | 0  |     int x = 0;  | 
158  | 0  |     int y = 0;  | 
159  | 0  |     int strLen = 6;  | 
160  | 0  |     if (y + 8 <= imgHeight && x + 8 * strLen <= imgWidth)  | 
161  | 0  |       GifDrawText8x8(&GifFile->SavedImages[i], 0, 0, "legend", 42);  | 
162  | 0  |   }  | 
163  |  | #if GIF_DEBUG  | 
164  |  |   ALOGD("FrameSequence_gif created with size %d %d, frames %d dur %ld", | 
165  |  |       GifFile->SWidth, GifFile->SHeight, GifFile->ImageCount, durationMs);  | 
166  |  |   for (int i = 0; i < GifFile->ImageCount; i++)  | 
167  |  |   { | 
168  |  |     DGifSavedExtensionToGCB(GifFile, i, &gcb);  | 
169  |  |     ALOGD("    Frame %d - must preserve %d, restore point %d, trans color %d", | 
170  |  |         i, preservedFrames[i], restoringFrames[i], gcb.TransparentColor);  | 
171  |  |   }  | 
172  |  | #endif  | 
173  | 0  |   const ColorMapObject *cmap = GifFile->SColorMap;  | 
174  | 0  |   if (cmap)  | 
175  | 0  |   { | 
176  |  |     // calculate bg color  | 
177  | 0  |     GraphicsControlBlock gcb;  | 
178  | 0  |     DGifSavedExtensionToGCB(GifFile, 0, &gcb);  | 
179  | 0  |     if (gcb.TransparentColor == NO_TRANSPARENT_COLOR && GifFile->SBackGroundColor < cmap->ColorCount)  | 
180  | 0  |     { | 
181  | 0  |       bgColor = gifColorToColor8888(cmap->Colors[GifFile->SBackGroundColor]);  | 
182  | 0  |     }  | 
183  | 0  |   }  | 
184  |  | 
  | 
185  | 0  |   DGifCloseFile(GifFile, &Error);  | 
186  | 0  |   free(gifData);  | 
187  | 0  |   delete[] preservedFrames;  | 
188  | 0  |   delete[] restoringFrames;  | 
189  | 0  |   return 0;  | 
190  | 0  | }  |