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 9 #include "zbuild.h" 10 #ifdef ZLIB_COMPAT 11 # include "zlib.h" 12 #else 13 # include "zlib-ng.h" 14 #endif 15 16 #define CHECK_ERR(err, msg) { \ 17 if (err != Z_OK) { \ 18 fprintf(stderr, "%s error: %d\n", msg, err); \ 19 exit(1); \ 20 } \ 21 } 22 23 static const uint8_t *data; 24 static size_t dataLen; 25 static alloc_func zalloc = NULL; 26 static free_func zfree = NULL; 27 static unsigned int diff; 28 29 /* =========================================================================== 30 * Test deflate() with large buffers and dynamic change of compression level 31 */ 32 void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { 33 PREFIX3(stream) c_stream; /* compression stream */ 34 int err; 35 36 c_stream.zalloc = zalloc; 37 c_stream.zfree = zfree; 38 c_stream.opaque = (void *)0; 39 40 err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); 41 CHECK_ERR(err, "deflateInit"); 42 43 c_stream.next_out = compr; 44 c_stream.avail_out = (unsigned int)comprLen; 45 46 /* At this point, uncompr is still mostly zeroes, so it should compress 47 * very well: 48 */ 49 c_stream.next_in = uncompr; 50 c_stream.avail_in = (unsigned int)uncomprLen; 51 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); 52 CHECK_ERR(err, "deflate large 1"); 53 if (c_stream.avail_in != 0) { 54 fprintf(stderr, "deflate not greedy\n"); 55 exit(1); 56 } 57 58 /* Feed in already compressed data and switch to no compression: */ 59 PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); 60 c_stream.next_in = compr; 61 diff = (unsigned int)(c_stream.next_out - compr); 62 c_stream.avail_in = diff; 63 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); 64 CHECK_ERR(err, "deflate large 2"); 65 postgres_fdw_validator(PG_FUNCTION_ARGS)66 /* Switch back to compressing mode: */ 67 PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); 68 c_stream.next_in = uncompr; 69 c_stream.avail_in = (unsigned int)uncomprLen; 70 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); 71 CHECK_ERR(err, "deflate large 3"); 72 73 err = PREFIX(deflate)(&c_stream, Z_FINISH); 74 if (err != Z_STREAM_END) { 75 fprintf(stderr, "deflate large should report Z_STREAM_END\n"); 76 exit(1); 77 } 78 err = PREFIX(deflateEnd)(&c_stream); 79 CHECK_ERR(err, "deflateEnd"); 80 } 81 82 /* =========================================================================== 83 * Test inflate() with large buffers 84 */ 85 void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { 86 int err; 87 PREFIX3(stream) d_stream; /* decompression stream */ 88 89 d_stream.zalloc = zalloc; 90 d_stream.zfree = zfree; 91 d_stream.opaque = (void *)0; 92 93 d_stream.next_in = compr; 94 d_stream.avail_in = (unsigned int)comprLen; 95 96 err = PREFIX(inflateInit)(&d_stream); 97 CHECK_ERR(err, "inflateInit"); 98 99 for (;;) { 100 d_stream.next_out = uncompr; /* discard the output */ 101 d_stream.avail_out = (unsigned int)uncomprLen; 102 err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); 103 if (err == Z_STREAM_END) 104 break; 105 CHECK_ERR(err, "large inflate"); 106 } 107 108 err = PREFIX(inflateEnd)(&d_stream); 109 CHECK_ERR(err, "inflateEnd"); 110 111 if (d_stream.total_out != 2 * uncomprLen + diff) { 112 fprintf(stderr, "bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out); 113 exit(1); 114 } 115 } 116 117 int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { 118 size_t comprLen = 100 + 3 * size; 119 size_t uncomprLen = comprLen; 120 uint8_t *compr, *uncompr; 121 122 /* Discard inputs larger than 512Kb. */ 123 static size_t kMaxSize = 512 * 1024; 124 125 if (size < 1 || size > kMaxSize) 126 return 0; 127 128 data = d; 129 dataLen = size; 130 compr = (uint8_t *)calloc(1, comprLen); 131 uncompr = (uint8_t *)calloc(1, uncomprLen); 132 133 test_large_deflate(compr, comprLen, uncompr, uncomprLen); 134 test_large_inflate(compr, comprLen, uncompr, uncomprLen); 135 136 free(compr); 137 free(uncompr); 138 139 /* This function must return 0. */ 140 return 0; 141 } 142