Coverage Report

Created: 2023-12-08 06:35

/src/dgif_fuzz_common.cc
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
1.92M
{
10
1.92M
  struct gifUserData *gud = (struct gifUserData *)gifFileType->UserData;
11
1.92M
  if (gud->gifLen == 0)
12
917
    return 0;
13
1.91M
  int read_len = (len > gud->gifLen ? gud->gifLen : len);
14
1.91M
  memcpy(gifByteType, gud->gifData, read_len);
15
1.91M
  gud->gifData += read_len;
16
1.91M
  gud->gifLen -= read_len;
17
1.91M
  return read_len;
18
1.92M
}
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
2.09k
{
40
2.09k
  GifFileType *GifFile;
41
2.09k
  int Error;
42
2.09k
  uint8_t *gifData = (uint8_t *)malloc(Size);
43
2.09k
  memcpy(gifData, Data, Size);
44
2.09k
  struct gifUserData gUData = {Size, gifData};
45
46
2.09k
  GifFile = DGifOpen((void *)&gUData, stub_input_reader, &Error);
47
2.09k
  if (GifFile == NULL)
48
95
  {
49
95
    free(gifData);
50
95
    return 0;
51
95
  }
52
1.99k
  if (DGifSlurp(GifFile) != GIF_OK)
53
1.77k
  {
54
1.77k
    DGifCloseFile(GifFile, &Error);
55
1.77k
    free(gifData);
56
1.77k
    return 0;
57
1.77k
  }
58
227
  GraphicsControlBlock gcb;
59
68.4k
  for (int i = 0; i < GifFile->ImageCount; i++)
60
68.1k
  {
61
68.1k
    DGifSavedExtensionToGCB(GifFile, i, &gcb);
62
68.1k
  }
63
227
  const ColorMapObject *cmap = GifFile->SColorMap;
64
227
  if (cmap)
65
61
  {
66
61
    DGifSavedExtensionToGCB(GifFile, 0, &gcb);
67
61
  }
68
227
  DGifCloseFile(GifFile, &Error);
69
227
  free(gifData);
70
227
  return 0;
71
1.99k
}
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
}