• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stddef.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <assert.h>
6 #include <stdlib.h>
7 #include <inttypes.h>
8 #include "zlib.h"
9 
10 #define CHECK_ERR(err, msg) { \
11     if (err != Z_OK) { \
12         fprintf(stderr, "%s error: %d\n", msg, err); \
13         exit(1); \
14     } \
15 }
16 
17 static const uint8_t *data;
18 static size_t dataLen;
19 static alloc_func zalloc = NULL;
20 static free_func zfree = NULL;
21 
22 /* ===========================================================================
23  * Test deflate() with small buffers
24  */
test_deflate(unsigned char * compr,size_t comprLen)25 void test_deflate(unsigned char *compr, size_t comprLen) {
26   z_stream c_stream; /* compression stream */
27   int err;
28   unsigned long len = dataLen;
29 
30   c_stream.zalloc = zalloc;
31   c_stream.zfree = zfree;
32   c_stream.opaque = (void *)0;
33 
34   err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
35   CHECK_ERR(err, "deflateInit");
36 
37   c_stream.next_in = (Bytef *)data;
38   c_stream.next_out = compr;
39 
40   while (c_stream.total_in != len && c_stream.total_out < comprLen) {
41     c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
42     err = deflate(&c_stream, Z_NO_FLUSH);
43     CHECK_ERR(err, "deflate small 1");
44   }
45   /* Finish the stream, still forcing small buffers: */
46   for (;;) {
47     c_stream.avail_out = 1;
48     err = deflate(&c_stream, Z_FINISH);
49     if (err == Z_STREAM_END)
50       break;
51     CHECK_ERR(err, "deflate small 2");
52   }
53 
54   err = deflateEnd(&c_stream);
55   CHECK_ERR(err, "deflateEnd");
56 }
57 
58 /* ===========================================================================
59  * Test inflate() with small buffers
60  */
test_inflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)61 void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr,
62                   size_t uncomprLen) {
63   int err;
64   z_stream d_stream; /* decompression stream */
65 
66   d_stream.zalloc = zalloc;
67   d_stream.zfree = zfree;
68   d_stream.opaque = (void *)0;
69 
70   d_stream.next_in = compr;
71   d_stream.avail_in = 0;
72   d_stream.next_out = uncompr;
73 
74   err = inflateInit(&d_stream);
75   CHECK_ERR(err, "inflateInit");
76 
77   while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
78     d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
79     err = inflate(&d_stream, Z_NO_FLUSH);
80     if (err == Z_STREAM_END)
81       break;
82     CHECK_ERR(err, "inflate");
83   }
84 
85   err = inflateEnd(&d_stream);
86   CHECK_ERR(err, "inflateEnd");
87 
88   if (memcmp(uncompr, data, dataLen)) {
89     fprintf(stderr, "bad inflate\n");
90     exit(1);
91   }
92 }
93 
LLVMFuzzerTestOneInput(const uint8_t * d,size_t size)94 int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) {
95   size_t comprLen = compressBound(size);
96   size_t uncomprLen = size;
97   uint8_t *compr, *uncompr;
98 
99   /* Discard inputs larger than 1Mb. */
100   static size_t kMaxSize = 1024 * 1024;
101 
102   if (size < 1 || size > kMaxSize)
103     return 0;
104 
105   data = d;
106   dataLen = size;
107   compr = (uint8_t *)calloc(1, comprLen);
108   uncompr = (uint8_t *)calloc(1, uncomprLen);
109 
110   test_deflate(compr, comprLen);
111   test_inflate(compr, comprLen, uncompr, uncomprLen);
112 
113   free(compr);
114   free(uncompr);
115 
116   /* This function must return 0. */
117   return 0;
118 }
119