1 /**********************************************************************
2   Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3 
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions
6   are met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in
11       the documentation and/or other materials provided with the
12       distribution.
13     * Neither the name of Intel Corporation nor the names of its
14       contributors may be used to endorse or promote products derived
15       from this software without specific prior written permission.
16 
17   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29 
30 #define _FILE_OFFSET_BITS 64
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35 #include <stdarg.h>
36 #include "igzip_lib.h"
37 #include "checksum_test_ref.h"
38 #include "inflate_std_vects.h"
39 #include <math.h>
40 #include "test.h"
41 #include "unaligned.h"
42 
43 #ifdef HAVE_GETOPT
44 #include <getopt.h>
45 #endif
46 
47 #ifndef RANDOMS
48 # define RANDOMS   0x40
49 #endif
50 #ifndef TEST_SEED
51 # define TEST_SEED 0x1234
52 #endif
53 
54 #define MAX_BITS_COUNT 20
55 #define MIN_BITS_COUNT 8
56 
57 #define IBUF_SIZE  (1024*1024)
58 
59 #define MAX_LARGE_COMP_BUF_SIZE (1024*1024)
60 
61 #define PAGE_SIZE 4*1024
62 
63 #define MAX_FILE_SIZE 0x7fff8fff
64 
65 #define str1 "Short test string"
66 #define str2 "one two three four five six seven eight nine ten eleven twelve " \
67 		 "thirteen fourteen fifteen sixteen"
68 
69 #define TYPE0_HDR_SIZE 5	/* Size of a type 0 blocks header in bytes */
70 #define TYPE0_MAX_SIZE 65535	/* Max length of a type 0 block in bytes (excludes the header) */
71 
72 #define MAX_LOOPS 20
73 /* Defines for the possible error conditions */
74 enum IGZIP_TEST_ERROR_CODES {
75 	IGZIP_COMP_OK = 0,
76 
77 	MALLOC_FAILED,
78 	FILE_READ_FAILED,
79 
80 	COMPRESS_INCORRECT_STATE,
81 	COMPRESS_INPUT_STREAM_INTEGRITY_ERROR,
82 	COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR,
83 	COMPRESS_END_OF_STREAM_NOT_SET,
84 	COMPRESS_ALL_INPUT_FAIL,
85 	COMPRESS_OUT_BUFFER_OVERFLOW,
86 	COMPRESS_LOOP_COUNT_OVERFLOW,
87 	COMPRESS_GENERAL_ERROR,
88 
89 	INFLATE_END_OF_INPUT,
90 	INFLATE_INVALID_BLOCK_HEADER,
91 	INFLATE_INVALID_SYMBOL,
92 	INFLATE_OUT_BUFFER_OVERFLOW,
93 	INFLATE_LEFTOVER_INPUT,
94 	INFLATE_INCORRECT_OUTPUT_SIZE,
95 	INFLATE_INVALID_LOOK_BACK_DISTANCE,
96 	INFLATE_INPUT_STREAM_INTEGRITY_ERROR,
97 	INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR,
98 	INVALID_GZIP_HEADER,
99 	INCORRECT_GZIP_TRAILER,
100 	INVALID_ZLIB_HEADER,
101 	INCORRECT_ZLIB_TRAILER,
102 
103 	UNSUPPORTED_METHOD,
104 
105 	INFLATE_GENERAL_ERROR,
106 
107 	INVALID_FLUSH_ERROR,
108 
109 	OVERFLOW_TEST_ERROR,
110 	RESULT_ERROR
111 };
112 
113 static const int hdr_bytes = 300;
114 
115 static const uint32_t gzip_trl_bytes = 8;
116 static const uint32_t zlib_trl_bytes = 4;
117 static const int gzip_extra_bytes = 18;	/* gzip_hdr_bytes + gzip_trl_bytes */
118 static const int zlib_extra_bytes = 6;	/* zlib_hdr_bytes + zlib_trl_bytes */
119 
120 int inflate_type = 0;
121 
122 struct isal_hufftables *hufftables = NULL;
123 struct isal_hufftables *hufftables_subset = NULL;
124 
125 #define HISTORY_SIZE 32*1024
126 #define MIN_LENGTH 3
127 #define MIN_DIST 1
128 
129 struct test_options {
130 	int test_seed;
131 	int randoms;
132 	int do_large_test;
133 	int verbose;
134 
135 };
136 
137 struct test_options options;
138 
init_options(void)139 void init_options(void)
140 {
141 	options.test_seed = TEST_SEED;
142 	options.randoms = RANDOMS;
143 	options.do_large_test = 1;
144 #ifdef VERBOSE
145 	options.verbose = 1;
146 #else
147 	options.verbose = 0;
148 #endif
149 }
150 
usage(void)151 void usage(void)
152 {
153 	fprintf(stderr,
154 		"Usage: igzip_rand_test [options] [FILES]\n"
155 		"  -h          help, print this message\n"
156 		"  -l          turn off large input test\n"
157 		"  -r <iter>   number of randoms for each test\n"
158 		"  -s <seed>   set rand() test seed\n"
159 		"  -v          enable verbose test log\n");
160 	exit(0);
161 }
162 
parse_options(int argc,char * argv[])163 size_t parse_options(int argc, char *argv[])
164 {
165 	init_options();
166 #ifdef HAVE_GETOPT
167 	int c;
168 	char optstring[] = "hlr:s:v";
169 	while ((c = getopt(argc, argv, optstring)) != -1) {
170 		switch (c) {
171 		case 'l':
172 			options.do_large_test = 0;
173 			break;
174 		case 'r':
175 			options.randoms = atoi(optarg);
176 			break;
177 		case 's':
178 			options.test_seed = atoi(optarg);
179 			break;
180 		case 'v':
181 			options.verbose = 1;
182 			break;
183 		case 'h':
184 		default:
185 			usage();
186 			break;
187 		}
188 	}
189 	return optind;
190 #else
191 	return 1;
192 #endif
193 }
194 
195 /* Create random compressible data. This is achieved by randomly choosing a
196  * random character, or to repeat previous data in the stream for a random
197  * length and look back distance. The probability of a random character or a
198  * repeat being chosen is semi-randomly chosen by setting max_repeat_data to be
199  * differing values */
create_rand_repeat_data(uint8_t * data,int size)200 void create_rand_repeat_data(uint8_t * data, int size)
201 {
202 	uint32_t next_data;
203 	uint8_t *data_start = data;
204 	uint32_t length, distance;
205 	uint32_t symbol_count = rand() % 255 + 1, swaps_left, tmp;
206 	uint32_t max_repeat_data = symbol_count;
207 	uint8_t symbols[256], *symbols_next, swap_val;
208 
209 	/* An array of the powers of 2 (except the final element which is 0) */
210 	const uint32_t power_of_2_array[] = {
211 		0x00000001, 0x00000002, 0x00000004, 0x00000008,
212 		0x00000010, 0x00000020, 0x00000040, 0x00000080,
213 		0x00000100, 0x00000200, 0x00000400, 0x00000800,
214 		0x00001000, 0x00002000, 0x00004000, 0x00008000,
215 		0x00010000, 0x00020000, 0x00040000, 0x00080000,
216 		0x00100000, 0x00200000, 0x00400000, 0x00800000,
217 		0x01000000, 0x02000000, 0x04000000, 0x08000000,
218 		0x10000000, 0x20000000, 0x40000000, 0x00000000
219 	};
220 
221 	uint32_t power = rand() % sizeof(power_of_2_array) / sizeof(uint32_t);
222 
223 	if (symbol_count > 128) {
224 		memset(symbols, 1, sizeof(symbols));
225 		swap_val = 0;
226 		swaps_left = 256 - symbol_count;
227 	} else {
228 		memset(symbols, 0, sizeof(symbols));
229 		swap_val = 1;
230 		swaps_left = symbol_count;
231 	}
232 
233 	while (swaps_left > 0) {
234 		tmp = rand() % 256;
235 		if (symbols[tmp] != swap_val) {
236 			symbols[tmp] = swap_val;
237 			swaps_left--;
238 		}
239 	}
240 
241 	symbols_next = symbols;
242 	for (tmp = 0; tmp < 256; tmp++) {
243 		if (symbols[tmp]) {
244 			*symbols_next = tmp;
245 			symbols_next++;
246 		}
247 	}
248 
249 	max_repeat_data += power_of_2_array[power];
250 
251 	if (size > 0) {
252 		size--;
253 		*data++ = rand();
254 	}
255 
256 	while (size > 0) {
257 		next_data = rand() % max_repeat_data;
258 		if (next_data < symbol_count) {
259 			*data++ = symbols[next_data];
260 			size--;
261 		} else if (size < 3) {
262 			*data++ = symbols[rand() % symbol_count];
263 			size--;
264 		} else {
265 			length = (rand() % 256) + MIN_LENGTH;
266 			if (length > size)
267 				length = (rand() % (size - 2)) + MIN_LENGTH;
268 
269 			distance = (rand() % HISTORY_SIZE) + MIN_DIST;
270 			if (distance > data - data_start)
271 				distance = (rand() % (data - data_start)) + MIN_DIST;
272 
273 			size -= length;
274 			if (distance <= length) {
275 				while (length-- > 0) {
276 					*data = *(data - distance);
277 					data++;
278 				}
279 			} else {
280 				memcpy(data, data - distance, length);
281 				data += length;
282 			}
283 		}
284 	}
285 }
286 
create_rand_dict(uint8_t * dict,uint32_t dict_len,uint8_t * buf,uint32_t buf_len)287 void create_rand_dict(uint8_t * dict, uint32_t dict_len, uint8_t * buf, uint32_t buf_len)
288 {
289 	uint32_t dict_chunk_size, buf_chunk_size;
290 	while (dict_len > 0) {
291 		dict_chunk_size = rand() % IGZIP_K;
292 		dict_chunk_size = (dict_len >= dict_chunk_size) ? dict_chunk_size : dict_len;
293 
294 		buf_chunk_size = rand() % IGZIP_K;
295 		buf_chunk_size = (buf_len >= buf_chunk_size) ? buf_chunk_size : buf_len;
296 
297 		if (rand() % 3 == 0 && buf_len >= dict_len)
298 			memcpy(dict, buf, dict_chunk_size);
299 		else
300 			create_rand_repeat_data(dict, dict_chunk_size);
301 
302 		dict_len -= dict_chunk_size;
303 		dict += dict_chunk_size;
304 		buf_len -= buf_chunk_size;
305 		buf += buf_chunk_size;
306 	}
307 
308 }
309 
get_rand_data_length(void)310 int get_rand_data_length(void)
311 {
312 	int max_mask =
313 	    (1 << ((rand() % (MAX_BITS_COUNT - MIN_BITS_COUNT)) + MIN_BITS_COUNT)) - 1;
314 	return rand() & max_mask;
315 }
316 
get_rand_level(void)317 int get_rand_level(void)
318 {
319 	return ISAL_DEF_MIN_LEVEL + rand() % (ISAL_DEF_MAX_LEVEL - ISAL_DEF_MIN_LEVEL + 1);
320 
321 }
322 
get_rand_level_buf_size(int level)323 int get_rand_level_buf_size(int level)
324 {
325 	int size;
326 	switch (level) {
327 	case 3:
328 		size = rand() % IBUF_SIZE + ISAL_DEF_LVL3_MIN;
329 		break;
330 	case 2:
331 		size = rand() % IBUF_SIZE + ISAL_DEF_LVL2_MIN;
332 		break;
333 	case 1:
334 	default:
335 		size = rand() % IBUF_SIZE + ISAL_DEF_LVL1_MIN;
336 	}
337 	return size;
338 }
339 
print_error(int error_code)340 void print_error(int error_code)
341 {
342 	switch (error_code) {
343 	case IGZIP_COMP_OK:
344 		break;
345 	case MALLOC_FAILED:
346 		printf("error: failed to allocate memory\n");
347 		break;
348 	case FILE_READ_FAILED:
349 		printf("error: failed to read in file\n");
350 		break;
351 	case COMPRESS_INCORRECT_STATE:
352 		printf("error: incorrect stream internal state\n");
353 		break;
354 	case COMPRESS_INPUT_STREAM_INTEGRITY_ERROR:
355 		printf("error: inconsistent stream input buffer\n");
356 		break;
357 	case COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR:
358 		printf("error: inconsistent stream output buffer\n");
359 		break;
360 	case COMPRESS_END_OF_STREAM_NOT_SET:
361 		printf("error: end of stream not set\n");
362 		break;
363 	case COMPRESS_ALL_INPUT_FAIL:
364 		printf("error: not all input data compressed\n");
365 		break;
366 	case COMPRESS_OUT_BUFFER_OVERFLOW:
367 		printf("error: output buffer overflow while compressing data\n");
368 		break;
369 	case COMPRESS_GENERAL_ERROR:
370 		printf("error: compression failed\n");
371 		break;
372 	case INFLATE_END_OF_INPUT:
373 		printf("error: did not decompress all input\n");
374 		break;
375 	case INFLATE_INVALID_BLOCK_HEADER:
376 		printf("error: invalid header\n");
377 		break;
378 	case INFLATE_INVALID_SYMBOL:
379 		printf("error: invalid symbol found when decompressing input\n");
380 		break;
381 	case INFLATE_OUT_BUFFER_OVERFLOW:
382 		printf("error: output buffer overflow while decompressing data\n");
383 		break;
384 	case INFLATE_GENERAL_ERROR:
385 		printf("error: decompression failed\n");
386 		break;
387 	case INFLATE_LEFTOVER_INPUT:
388 		printf("error: the trailer of igzip output contains junk\n");
389 		break;
390 	case INFLATE_INCORRECT_OUTPUT_SIZE:
391 		printf("error: incorrect amount of data was decompressed\n");
392 		break;
393 	case INFLATE_INVALID_LOOK_BACK_DISTANCE:
394 		printf("error: invalid look back distance found while decompressing\n");
395 		break;
396 	case INFLATE_INPUT_STREAM_INTEGRITY_ERROR:
397 		printf("error: inconsistent input buffer\n");
398 		break;
399 	case INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR:
400 		printf("error: inconsistent output buffer\n");
401 		break;
402 	case INVALID_GZIP_HEADER:
403 		printf("error: incorrect gzip header found when inflating data\n");
404 		break;
405 	case INCORRECT_GZIP_TRAILER:
406 		printf("error: incorrect gzip trailer found when inflating data\n");
407 		break;
408 	case INVALID_ZLIB_HEADER:
409 		printf("error: incorrect zlib header found when inflating data\n");
410 		break;
411 	case INCORRECT_ZLIB_TRAILER:
412 		printf("error: incorrect zlib trailer found when inflating data\n");
413 		break;
414 	case UNSUPPORTED_METHOD:
415 		printf("error: invalid compression method in wrapper header\n");
416 		break;
417 	case INVALID_FLUSH_ERROR:
418 		printf("error: invalid flush did not cause compression to error\n");
419 		break;
420 	case RESULT_ERROR:
421 		printf("error: decompressed data is not the same as the compressed data\n");
422 		break;
423 	case OVERFLOW_TEST_ERROR:
424 		printf("error: overflow undetected\n");
425 		break;
426 	default:
427 		printf("error: unknown error code\n");
428 	}
429 }
430 
print_uint8_t(uint8_t * array,uint64_t length)431 void print_uint8_t(uint8_t * array, uint64_t length)
432 {
433 	const int line_size = 16;
434 	int i;
435 
436 	printf("Length = %lu", length);
437 	for (i = 0; i < length; i++) {
438 		if ((i % line_size) == 0)
439 			printf("\n0x%08x\t", i);
440 		else
441 			printf(" ");
442 		printf("0x%02x,", array[i]);
443 	}
444 	printf("\n");
445 }
446 
log_print(char * format,...)447 void log_print(char *format, ...)
448 {
449 	va_list args;
450 	va_start(args, format);
451 
452 	if (options.verbose)
453 		vfprintf(stdout, format, args);
454 
455 	va_end(args);
456 }
457 
log_uint8_t(uint8_t * array,uint64_t length)458 void log_uint8_t(uint8_t * array, uint64_t length)
459 {
460 	if (options.verbose)
461 		print_uint8_t(array, length);
462 }
463 
log_error(int error_code)464 void log_error(int error_code)
465 {
466 	if (options.verbose)
467 		print_error(error_code);
468 }
469 
check_gzip_trl(uint64_t gzip_trl,uint32_t inflate_crc,uint8_t * uncompress_buf,uint32_t uncompress_len)470 uint32_t check_gzip_trl(uint64_t gzip_trl, uint32_t inflate_crc, uint8_t * uncompress_buf,
471 			uint32_t uncompress_len)
472 {
473 	uint64_t trl, ret = 0;
474 	uint32_t crc;
475 
476 	crc = crc32_gzip_refl_ref(0, uncompress_buf, uncompress_len);
477 	trl = ((uint64_t) uncompress_len << 32) | crc;
478 
479 	if (crc != inflate_crc || trl != gzip_trl)
480 		ret = INCORRECT_GZIP_TRAILER;
481 
482 	return ret;
483 }
484 
check_zlib_trl(uint32_t zlib_trl,uint32_t inflate_adler,uint8_t * uncompress_buf,uint32_t uncompress_len)485 uint32_t check_zlib_trl(uint32_t zlib_trl, uint32_t inflate_adler, uint8_t * uncompress_buf,
486 			uint32_t uncompress_len)
487 {
488 	uint32_t trl, ret = 0;
489 	uint32_t adler;
490 
491 	adler = adler_ref(1, uncompress_buf, uncompress_len);
492 
493 	trl =
494 	    (adler >> 24) | ((adler >> 8) & 0xFF00) | (adler << 24) | ((adler & 0xFF00) << 8);
495 
496 	if (adler != inflate_adler || trl != zlib_trl) {
497 		ret = INCORRECT_ZLIB_TRAILER;
498 	}
499 
500 	return ret;
501 }
502 
inflate_stateless_pass(uint8_t * compress_buf,uint64_t compress_len,uint8_t * uncompress_buf,uint32_t * uncompress_len,uint32_t gzip_flag)503 int inflate_stateless_pass(uint8_t * compress_buf, uint64_t compress_len,
504 			   uint8_t * uncompress_buf, uint32_t * uncompress_len,
505 			   uint32_t gzip_flag)
506 {
507 	struct inflate_state state;
508 	int ret = 0, offset = 0;
509 	struct isal_gzip_header gz_hdr;
510 	struct isal_zlib_header z_hdr;
511 
512 	state.next_in = compress_buf;
513 	state.avail_in = compress_len;
514 	state.next_out = uncompress_buf;
515 	state.avail_out = *uncompress_len;
516 
517 	if (gzip_flag == IGZIP_GZIP) {
518 		if (rand() % 2 == 0) {
519 			memset(&gz_hdr, 0, sizeof(gz_hdr));
520 			isal_inflate_reset(&state);
521 			state.tmp_in_size = 0;
522 			gzip_flag = ISAL_GZIP_NO_HDR_VER;
523 
524 			isal_read_gzip_header(&state, &gz_hdr);
525 		}
526 	} else if (gzip_flag == IGZIP_ZLIB) {
527 		if (rand() % 2 == 0) {
528 			memset(&z_hdr, 0, sizeof(z_hdr));
529 			isal_inflate_reset(&state);
530 			gzip_flag = ISAL_ZLIB_NO_HDR_VER;
531 			isal_read_zlib_header(&state, &z_hdr);
532 		}
533 	}
534 
535 	state.crc_flag = gzip_flag;
536 
537 	ret = isal_inflate_stateless(&state);
538 
539 	*uncompress_len = state.total_out;
540 
541 	if (gzip_flag) {
542 		if (gzip_flag == IGZIP_GZIP || gzip_flag == IGZIP_GZIP_NO_HDR
543 		    || gzip_flag == ISAL_GZIP_NO_HDR_VER) {
544 			if (gzip_flag == IGZIP_GZIP || gzip_flag == ISAL_GZIP_NO_HDR_VER)
545 				offset = gzip_trl_bytes;
546 
547 			if (!ret)
548 				ret =
549 				    check_gzip_trl(load_u64(state.next_in - offset),
550 						   state.crc, uncompress_buf, *uncompress_len);
551 			else if (ret == ISAL_INCORRECT_CHECKSUM)
552 				ret = INCORRECT_GZIP_TRAILER;
553 			state.avail_in -= (gzip_trl_bytes - offset);
554 		} else if (gzip_flag == IGZIP_ZLIB || gzip_flag == IGZIP_ZLIB_NO_HDR
555 			   || gzip_flag == ISAL_ZLIB_NO_HDR_VER) {
556 			if (gzip_flag == IGZIP_ZLIB || gzip_flag == ISAL_ZLIB_NO_HDR_VER)
557 				offset = zlib_trl_bytes;
558 
559 			if (!ret)
560 				ret =
561 				    check_zlib_trl(load_u32(state.next_in - offset),
562 						   state.crc, uncompress_buf, *uncompress_len);
563 			else if (ret == ISAL_INCORRECT_CHECKSUM)
564 				ret = INCORRECT_ZLIB_TRAILER;
565 			state.avail_in -= (zlib_trl_bytes - offset);
566 
567 		}
568 
569 	}
570 
571 	if (ret == 0 && state.avail_in != 0)
572 		ret = INFLATE_LEFTOVER_INPUT;
573 
574 	return ret;
575 }
576 
577 /* Check if that the state of the data stream is consistent */
inflate_state_valid_check(struct inflate_state * state,uint8_t * in_buf,uint32_t in_size,uint8_t * out_buf,uint32_t out_size,uint32_t in_processed,uint32_t out_processed,uint32_t data_size)578 int inflate_state_valid_check(struct inflate_state *state, uint8_t * in_buf, uint32_t in_size,
579 			      uint8_t * out_buf, uint32_t out_size, uint32_t in_processed,
580 			      uint32_t out_processed, uint32_t data_size)
581 {
582 	uint32_t in_buffer_size, total_out, out_buffer_size;
583 
584 	in_buffer_size = (in_size == 0) ? 0 : state->next_in - in_buf + state->avail_in;
585 
586 	/* Check for a consistent amount of data processed */
587 	if (in_buffer_size != in_size)
588 		return INFLATE_INPUT_STREAM_INTEGRITY_ERROR;
589 
590 	total_out =
591 	    (out_size == 0) ? out_processed : out_processed + (state->next_out - out_buf);
592 	out_buffer_size = (out_size == 0) ? 0 : state->next_out - out_buf + state->avail_out;
593 
594 	/* Check for a consistent amount of data compressed */
595 	if (total_out != state->total_out || out_buffer_size != out_size)
596 		return INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR;
597 
598 	return 0;
599 }
600 
601 /* Performs compression with checks to discover and verify the state of the
602  * stream
603  * state: inflate data structure which has been initialized to use
604  * in_buf and out_buf as the buffers
605  * compress_len: size of all input compressed data
606  * data_size: size of all available output buffers
607  * in_buf: next buffer of data to be inflated
608  * in_size: size of in_buf
609  * out_buf: next out put buffer where data is stored
610  * out_size: size of out_buf
611  * in_processed: the amount of input data which has been loaded into buffers
612  * to be inflated, this includes the data in in_buf
613  * out_processed: the amount of output data which has been decompressed and stored,
614  * this does not include the data in the current out_buf
615 */
isal_inflate_with_checks(struct inflate_state * state,uint32_t compress_len,uint32_t data_size,uint8_t * in_buf,uint32_t in_size,uint32_t in_processed,uint8_t * out_buf,uint32_t out_size,uint32_t out_processed)616 int isal_inflate_with_checks(struct inflate_state *state, uint32_t compress_len,
617 			     uint32_t data_size, uint8_t * in_buf, uint32_t in_size,
618 			     uint32_t in_processed, uint8_t * out_buf, uint32_t out_size,
619 			     uint32_t out_processed)
620 {
621 	int ret, stream_check = 0;
622 
623 	ret = isal_inflate(state);
624 
625 	/* Verify the stream is in a valid state when no errors occured */
626 	if (ret >= 0) {
627 		stream_check =
628 		    inflate_state_valid_check(state, in_buf, in_size, out_buf, out_size,
629 					      in_processed, out_processed, data_size);
630 	}
631 
632 	if (stream_check != 0)
633 		return stream_check;
634 
635 	return ret;
636 
637 }
638 
inflate_multi_pass(uint8_t * compress_buf,uint64_t compress_len,uint8_t * uncompress_buf,uint32_t * uncompress_len,uint32_t gzip_flag,uint8_t * dict,uint32_t dict_len,uint32_t hist_bits)639 int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
640 		       uint8_t * uncompress_buf, uint32_t * uncompress_len, uint32_t gzip_flag,
641 		       uint8_t * dict, uint32_t dict_len, uint32_t hist_bits)
642 {
643 	struct inflate_state *state = NULL;
644 	int ret = 0;
645 	uint8_t *comp_tmp = NULL, *uncomp_tmp = NULL;
646 	uint32_t comp_tmp_size = 0, uncomp_tmp_size = 0;
647 	uint32_t comp_processed = 0, uncomp_processed = 0;
648 	int32_t read_in_old = 0;
649 	uint32_t reset_test_flag = 0;
650 
651 	state = malloc(sizeof(struct inflate_state));
652 	if (state == NULL) {
653 		printf("Failed to allocate memory\n");
654 		exit(0);
655 	}
656 
657 	create_rand_repeat_data((uint8_t *) state, sizeof(state));
658 	isal_inflate_init(state);
659 
660 	if (rand() % 4 == 0) {
661 		/* Test reset */
662 		reset_test_flag = 1;
663 		create_rand_repeat_data((uint8_t *) state, sizeof(state));
664 	}
665 
666 	if (gzip_flag == IGZIP_GZIP_NO_HDR) {
667 		if (rand() % 2 == 0)
668 			compress_len -= gzip_trl_bytes;
669 		else
670 			gzip_flag = ISAL_GZIP_NO_HDR_VER;
671 	} else if (gzip_flag == IGZIP_ZLIB_NO_HDR) {
672 		if (rand() % 2 == 0)
673 			compress_len -= zlib_trl_bytes;
674 		else
675 			gzip_flag = ISAL_ZLIB_NO_HDR_VER;
676 	}
677 
678 	state->next_in = NULL;
679 	state->next_out = NULL;
680 	state->avail_in = 0;
681 	state->avail_out = 0;
682 	state->crc_flag = gzip_flag;
683 	state->hist_bits = hist_bits;
684 
685 	if (reset_test_flag)
686 		isal_inflate_reset(state);
687 
688 	if (dict != NULL)
689 		isal_inflate_set_dict(state, dict, dict_len);
690 
691 	while (1) {
692 		if (state->avail_in == 0) {
693 			comp_tmp_size = rand() % (compress_len + 1);
694 
695 			if (comp_tmp_size >= compress_len - comp_processed)
696 				comp_tmp_size = compress_len - comp_processed;
697 
698 			if (comp_tmp_size != 0) {
699 				if (comp_tmp != NULL) {
700 					free(comp_tmp);
701 					comp_tmp = NULL;
702 				}
703 
704 				comp_tmp = malloc(comp_tmp_size);
705 
706 				if (comp_tmp == NULL) {
707 					printf("Failed to allocate memory\n");
708 					return MALLOC_FAILED;
709 				}
710 
711 				memcpy(comp_tmp, compress_buf + comp_processed, comp_tmp_size);
712 				comp_processed += comp_tmp_size;
713 
714 				state->next_in = comp_tmp;
715 				state->avail_in = comp_tmp_size;
716 			}
717 		}
718 
719 		if (state->avail_out == 0) {
720 			/* Save uncompressed data into uncompress_buf */
721 			if (uncomp_tmp != NULL) {
722 				memcpy(uncompress_buf + uncomp_processed, uncomp_tmp,
723 				       uncomp_tmp_size);
724 				uncomp_processed += uncomp_tmp_size;
725 			}
726 
727 			uncomp_tmp_size = rand() % (*uncompress_len + 1);
728 
729 			/* Limit size of buffer to be smaller than maximum */
730 			if (uncomp_tmp_size > *uncompress_len - uncomp_processed)
731 				uncomp_tmp_size = *uncompress_len - uncomp_processed;
732 
733 			if (uncomp_tmp_size != 0) {
734 
735 				if (uncomp_tmp != NULL) {
736 					fflush(0);
737 					free(uncomp_tmp);
738 					uncomp_tmp = NULL;
739 				}
740 
741 				uncomp_tmp = malloc(uncomp_tmp_size);
742 				if (uncomp_tmp == NULL) {
743 					printf("Failed to allocate memory\n");
744 					return MALLOC_FAILED;
745 				}
746 
747 				state->avail_out = uncomp_tmp_size;
748 				state->next_out = uncomp_tmp;
749 			}
750 		}
751 
752 		log_print("Pre inflate\n");
753 		log_print
754 		    ("compressed_size = 0x%05lx, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x\n",
755 		     compress_len, comp_processed, comp_tmp_size, state->avail_in);
756 		log_print
757 		    ("data_size       = 0x%05x, out_processed  = 0x%05x, out_size  = 0x%05x, avail_out  = 0x%05x, total_out  = 0x%05x\n",
758 		     *uncompress_len, uncomp_processed, uncomp_tmp_size, state->avail_out,
759 		     state->total_out);
760 
761 		ret = isal_inflate_with_checks(state, compress_len, *uncompress_len, comp_tmp,
762 					       comp_tmp_size, comp_processed, uncomp_tmp,
763 					       uncomp_tmp_size, uncomp_processed);
764 
765 		log_print("Post inflate\n");
766 		log_print
767 		    ("compressed_size = 0x%05lx, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x\n",
768 		     compress_len, comp_processed, comp_tmp_size, state->avail_in);
769 		log_print
770 		    ("data_size       = 0x%05x, out_processed  = 0x%05x, out_size  = 0x%05x, avail_out  = 0x%05x, total_out  = 0x%05x\n",
771 		     *uncompress_len, uncomp_processed, uncomp_tmp_size, state->avail_out,
772 		     state->total_out);
773 
774 		if (state->block_state == ISAL_BLOCK_FINISH || ret != 0) {
775 			memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, uncomp_tmp_size);
776 			*uncompress_len = state->total_out;
777 			break;
778 		}
779 
780 		if (*uncompress_len - uncomp_processed == 0 && state->avail_out == 0
781 		    && state->tmp_out_valid - state->tmp_out_processed > 0) {
782 			ret = ISAL_OUT_OVERFLOW;
783 			break;
784 		}
785 
786 		if (compress_len - comp_processed == 0 && state->avail_in == 0
787 		    && (state->block_state != ISAL_BLOCK_INPUT_DONE)
788 		    && state->tmp_out_valid - state->tmp_out_processed == 0) {
789 			if (state->read_in_length == read_in_old) {
790 				ret = ISAL_END_INPUT;
791 				break;
792 			}
793 			read_in_old = state->read_in_length;
794 		}
795 	}
796 
797 	if (gzip_flag) {
798 		if (!ret) {
799 			if (gzip_flag == IGZIP_GZIP || gzip_flag == IGZIP_GZIP_NO_HDR
800 			    || gzip_flag == ISAL_GZIP_NO_HDR_VER) {
801 				if (gzip_flag == ISAL_GZIP_NO_HDR_VER
802 				    || gzip_flag == IGZIP_GZIP)
803 					compress_len -= gzip_trl_bytes;
804 				ret =
805 				    check_gzip_trl(load_u64(compress_buf + compress_len),
806 						   state->crc, uncompress_buf,
807 						   *uncompress_len);
808 			} else if (gzip_flag == IGZIP_ZLIB_NO_HDR) {
809 				if (gzip_flag == IGZIP_ZLIB
810 				    || gzip_flag == ISAL_ZLIB_NO_HDR_VER)
811 					compress_len -= zlib_trl_bytes;
812 				ret =
813 				    check_zlib_trl(load_u32(compress_buf + compress_len),
814 						   state->crc, uncompress_buf,
815 						   *uncompress_len);
816 			}
817 		}
818 	}
819 	if (ret == 0 && state->avail_in != 0)
820 		ret = INFLATE_LEFTOVER_INPUT;
821 
822 	if (comp_tmp != NULL) {
823 		free(comp_tmp);
824 		comp_tmp = NULL;
825 	}
826 
827 	if (uncomp_tmp != NULL) {
828 		free(uncomp_tmp);
829 		uncomp_tmp = NULL;
830 	}
831 
832 	free(state);
833 	return ret;
834 }
835 
inflate_ret_to_code(int ret)836 int inflate_ret_to_code(int ret)
837 {
838 	switch (ret) {
839 	case ISAL_DECOMP_OK:
840 		return 0;
841 	case ISAL_END_INPUT:
842 		return INFLATE_END_OF_INPUT;
843 	case ISAL_OUT_OVERFLOW:
844 		return INFLATE_OUT_BUFFER_OVERFLOW;
845 	case ISAL_INVALID_BLOCK:
846 		return INFLATE_INVALID_BLOCK_HEADER;
847 	case ISAL_INVALID_SYMBOL:
848 		return INFLATE_INVALID_SYMBOL;
849 	case ISAL_INVALID_LOOKBACK:
850 		return INFLATE_INVALID_LOOK_BACK_DISTANCE;
851 	default:
852 		return INFLATE_GENERAL_ERROR;
853 	}
854 }
855 
856 /* Inflate the  compressed data and check that the decompressed data agrees with the input data */
inflate_check(uint8_t * z_buf,uint32_t z_size,uint8_t * in_buf,uint32_t in_size,uint32_t gzip_flag,uint8_t * dict,uint32_t dict_len,uint32_t hist_bits)857 int inflate_check(uint8_t * z_buf, uint32_t z_size, uint8_t * in_buf, uint32_t in_size,
858 		  uint32_t gzip_flag, uint8_t * dict, uint32_t dict_len, uint32_t hist_bits)
859 {
860 	/* Test inflate with reference inflate */
861 
862 	int ret = 0;
863 	uint32_t test_size = in_size;
864 	uint8_t *test_buf = NULL;
865 	int mem_result = 0;
866 	int gzip_hdr_result = 0, gzip_trl_result = 0;
867 
868 	if (in_size > 0) {
869 		assert(in_buf != NULL);
870 		test_buf = malloc(test_size);
871 		if (test_buf == NULL)
872 			return MALLOC_FAILED;
873 	}
874 
875 	if (test_buf != NULL)
876 		memset(test_buf, 0xff, test_size);
877 
878 	if (inflate_type == 0 && dict == NULL) {
879 		ret = inflate_stateless_pass(z_buf, z_size, test_buf, &test_size, gzip_flag);
880 		inflate_type = 1;
881 	} else {
882 		ret =
883 		    inflate_multi_pass(z_buf, z_size, test_buf, &test_size, gzip_flag, dict,
884 				       dict_len, hist_bits);
885 		inflate_type = 0;
886 	}
887 
888 	if (test_buf != NULL)
889 		mem_result = memcmp(in_buf, test_buf, in_size);
890 
891 	if (options.verbose && mem_result) {
892 		int i;
893 		for (i = 0; i < in_size; i++) {
894 			if (in_buf[i] != test_buf[i]) {
895 				log_print
896 				    ("First incorrect data at 0x%x of 0x%x, 0x%x != 0x%x\n", i,
897 				     in_size, in_buf[i], test_buf[i]);
898 				break;
899 			}
900 		}
901 	}
902 
903 	if (test_buf != NULL)
904 		free(test_buf);
905 	switch (ret) {
906 	case 0:
907 		break;
908 	case ISAL_END_INPUT:
909 		return INFLATE_END_OF_INPUT;
910 		break;
911 	case ISAL_INVALID_BLOCK:
912 		return INFLATE_INVALID_BLOCK_HEADER;
913 		break;
914 	case ISAL_INVALID_SYMBOL:
915 		return INFLATE_INVALID_SYMBOL;
916 		break;
917 	case ISAL_OUT_OVERFLOW:
918 		return INFLATE_OUT_BUFFER_OVERFLOW;
919 		break;
920 	case ISAL_INVALID_LOOKBACK:
921 		return INFLATE_INVALID_LOOK_BACK_DISTANCE;
922 		break;
923 	case INFLATE_LEFTOVER_INPUT:
924 		return INFLATE_LEFTOVER_INPUT;
925 		break;
926 	case INCORRECT_GZIP_TRAILER:
927 		gzip_trl_result = INCORRECT_GZIP_TRAILER;
928 		break;
929 	case INCORRECT_ZLIB_TRAILER:
930 		gzip_trl_result = INCORRECT_ZLIB_TRAILER;
931 		break;
932 	case ISAL_INCORRECT_CHECKSUM:
933 		if (gzip_flag == IGZIP_GZIP || gzip_flag == IGZIP_GZIP_NO_HDR
934 		    || gzip_flag == ISAL_GZIP_NO_HDR_VER)
935 			gzip_trl_result = INCORRECT_GZIP_TRAILER;
936 		else if (gzip_flag == IGZIP_ZLIB || gzip_flag == IGZIP_ZLIB_NO_HDR
937 			 || gzip_flag == ISAL_ZLIB_NO_HDR_VER)
938 			gzip_trl_result = INCORRECT_GZIP_TRAILER;
939 		break;
940 	case ISAL_UNSUPPORTED_METHOD:
941 		return UNSUPPORTED_METHOD;
942 	case INFLATE_INPUT_STREAM_INTEGRITY_ERROR:
943 		return INFLATE_INPUT_STREAM_INTEGRITY_ERROR;
944 		break;
945 	case INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR:
946 		return INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR;
947 		break;
948 	default:
949 		return INFLATE_GENERAL_ERROR;
950 		break;
951 	}
952 
953 	if (test_size != in_size)
954 		return INFLATE_INCORRECT_OUTPUT_SIZE;
955 
956 	if (mem_result)
957 		return RESULT_ERROR;
958 
959 	if (gzip_hdr_result == INVALID_GZIP_HEADER)
960 		return INVALID_GZIP_HEADER;
961 
962 	else if (gzip_hdr_result == INVALID_ZLIB_HEADER)
963 		return INVALID_ZLIB_HEADER;
964 
965 	if (gzip_trl_result == INCORRECT_GZIP_TRAILER)
966 		return INCORRECT_GZIP_TRAILER;
967 
968 	else if (gzip_trl_result == INCORRECT_ZLIB_TRAILER)
969 		return INCORRECT_ZLIB_TRAILER;
970 
971 	return 0;
972 }
973 
974 /* Check if that the state of the data stream is consistent */
stream_valid_check(struct isal_zstream * stream,uint8_t * in_buf,uint32_t in_size,uint8_t * out_buf,uint32_t out_size,uint32_t in_processed,uint32_t out_processed,uint32_t data_size)975 int stream_valid_check(struct isal_zstream *stream, uint8_t * in_buf, uint32_t in_size,
976 		       uint8_t * out_buf, uint32_t out_size, uint32_t in_processed,
977 		       uint32_t out_processed, uint32_t data_size)
978 {
979 	uint32_t total_in, in_buffer_size, total_out, out_buffer_size;
980 
981 	total_in =
982 	    (in_size ==
983 	     0) ? in_processed : (in_processed - in_size) + (stream->next_in - in_buf);
984 	in_buffer_size = (in_size == 0) ? 0 : stream->next_in - in_buf + stream->avail_in;
985 
986 	/* Check for a consistent amount of data processed */
987 	if (total_in != stream->total_in || in_buffer_size != in_size)
988 		return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR;
989 
990 	total_out =
991 	    (out_size == 0) ? out_processed : out_processed + (stream->next_out - out_buf);
992 	out_buffer_size = (out_size == 0) ? 0 : stream->next_out - out_buf + stream->avail_out;
993 
994 	/* Check for a consistent amount of data compressed */
995 	if (total_out != stream->total_out || out_buffer_size != out_size) {
996 		return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR;
997 	}
998 
999 	return 0;
1000 }
1001 
1002 /* Performs compression with checks to discover and verify the state of the
1003  * stream
1004  * stream: compress data structure which has been initialized to use
1005  * in_buf and out_buf as the buffers
1006  * data_size: size of all input data
1007  * compressed_size: size of all available output buffers
1008  * in_buf: next buffer of data to be compressed
1009  * in_size: size of in_buf
1010  * out_buf: next out put buffer where data is stored
1011  * out_size: size of out_buf
1012  * in_processed: the amount of input data which has been loaded into buffers
1013  * to be compressed, this includes the data in in_buf
1014  * out_processed: the amount of output data which has been compressed and stored,
1015  * this does not include the data in the current out_buf
1016 */
isal_deflate_with_checks(struct isal_zstream * stream,uint32_t data_size,uint32_t compressed_size,uint8_t * in_buf,uint32_t in_size,uint32_t in_processed,uint8_t * out_buf,uint32_t out_size,uint32_t out_processed)1017 int isal_deflate_with_checks(struct isal_zstream *stream, uint32_t data_size,
1018 			     uint32_t compressed_size, uint8_t * in_buf, uint32_t in_size,
1019 			     uint32_t in_processed, uint8_t * out_buf, uint32_t out_size,
1020 			     uint32_t out_processed)
1021 {
1022 	int ret, stream_check;
1023 	struct isal_zstate *state = &stream->internal_state;
1024 
1025 	log_print("Pre compression\n");
1026 	log_print
1027 	    ("data_size       = 0x%05x, in_processed  = 0x%05x, in_size  = 0x%05x, avail_in  = 0x%05x, total_in  = 0x%05x\n",
1028 	     data_size, in_processed, in_size, stream->avail_in, stream->total_in);
1029 	log_print
1030 	    ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n",
1031 	     compressed_size, out_processed, out_size, stream->avail_out, stream->total_out);
1032 
1033 	ret = isal_deflate(stream);
1034 
1035 	log_print("Post compression\n");
1036 	log_print
1037 	    ("data_size       = 0x%05x, in_processed  = 0x%05x, in_size  = 0x%05x, avail_in  = 0x%05x, total_in  = 0x%05x\n",
1038 	     data_size, in_processed, in_size, stream->avail_in, stream->total_in);
1039 	log_print
1040 	    ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n",
1041 	     compressed_size, out_processed, out_size, stream->avail_out, stream->total_out);
1042 	log_print("\n\n");
1043 
1044 	/* Verify the stream is in a valid state */
1045 	stream_check = stream_valid_check(stream, in_buf, in_size, out_buf, out_size,
1046 					  in_processed, out_processed, data_size);
1047 
1048 	if (stream_check != 0)
1049 		return stream_check;
1050 
1051 	if (ret != IGZIP_COMP_OK)
1052 		return COMPRESS_GENERAL_ERROR;
1053 
1054 	/* Check if the compression is completed */
1055 	if (state->state != ZSTATE_END)
1056 		if (compressed_size - out_processed - (out_size - stream->avail_out) <= 0)
1057 			return COMPRESS_OUT_BUFFER_OVERFLOW;
1058 
1059 	return ret;
1060 
1061 }
1062 
set_random_hufftable(struct isal_zstream * stream,int level,uint8_t * data,uint32_t data_size)1063 void set_random_hufftable(struct isal_zstream *stream, int level, uint8_t * data,
1064 			  uint32_t data_size)
1065 {
1066 	struct isal_hufftables *huff = hufftables;
1067 	struct isal_huff_histogram hist;
1068 	if (level == 0 || rand() % 16 == 0) {
1069 		if (rand() % 8 == 0) {
1070 			huff = hufftables_subset;
1071 			memset(&hist, 0, sizeof(hist));
1072 			isal_update_histogram(data, data_size, &hist);
1073 			isal_create_hufftables_subset(huff, &hist);
1074 		}
1075 
1076 		isal_deflate_set_hufftables(stream, huff, rand() % 4);
1077 	}
1078 }
1079 
1080 /* Compress the input data into the output buffer where the input buffer and
1081  * output buffer are randomly segmented to test state information for the
1082  * compression*/
compress_multi_pass(uint8_t * data,uint32_t data_size,uint8_t * compressed_buf,uint32_t * compressed_size,uint32_t flush_type,uint32_t gzip_flag,uint32_t level,uint8_t * dict,uint32_t dict_len,uint32_t hist_bits)1083 int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1084 			uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
1085 			uint32_t level, uint8_t * dict, uint32_t dict_len, uint32_t hist_bits)
1086 {
1087 	int ret = IGZIP_COMP_OK;
1088 	uint8_t *in_buf = NULL, *out_buf = NULL;
1089 	uint32_t in_size = 0, out_size = 0;
1090 	uint32_t in_processed = 0, out_processed = 0;
1091 	struct isal_zstream *stream;
1092 	struct isal_zstate *state;
1093 	uint32_t loop_count = 0;
1094 	uint32_t level_buf_size;
1095 	uint8_t *level_buf = NULL;
1096 	struct isal_hufftables *huff_tmp;
1097 	uint32_t reset_test_flag = 0;
1098 	uint8_t tmp_symbol;
1099 	int no_mod = 0;
1100 	struct isal_dict dict_str;
1101 
1102 	log_print("Starting Compress Multi Pass\n");
1103 
1104 	stream = malloc(sizeof(*stream));
1105 	if (stream == NULL)
1106 		return MALLOC_FAILED;
1107 	state = &stream->internal_state;
1108 
1109 	create_rand_repeat_data((uint8_t *) stream, sizeof(*stream));
1110 
1111 	isal_deflate_init(stream);
1112 
1113 	if (state->state != ZSTATE_NEW_HDR)
1114 		return COMPRESS_INCORRECT_STATE;
1115 
1116 	if (rand() % 4 == 0) {
1117 		/* Test reset */
1118 		reset_test_flag = 1;
1119 		huff_tmp = stream->hufftables;
1120 		create_rand_repeat_data((uint8_t *) stream, sizeof(*stream));
1121 
1122 		/* Restore variables not necessarily set by user */
1123 		stream->hufftables = huff_tmp;
1124 		stream->end_of_stream = 0;
1125 		stream->level = 0;
1126 		stream->level_buf = NULL;
1127 		stream->level_buf_size = 0;
1128 	}
1129 
1130 	stream->flush = flush_type;
1131 	stream->end_of_stream = 0;
1132 
1133 	/* These are set here to allow the loop to run correctly */
1134 	stream->avail_in = 0;
1135 	stream->avail_out = 0;
1136 	stream->gzip_flag = gzip_flag;
1137 	stream->level = level;
1138 	stream->hist_bits = hist_bits;
1139 
1140 	if (level >= 1) {
1141 		level_buf_size = get_rand_level_buf_size(stream->level);
1142 		level_buf = malloc(level_buf_size);
1143 		create_rand_repeat_data(level_buf, level_buf_size);
1144 		stream->level_buf = level_buf;
1145 		stream->level_buf_size = level_buf_size;
1146 	}
1147 
1148 	if (reset_test_flag)
1149 		isal_deflate_reset(stream);
1150 
1151 	if (dict != NULL) {
1152 		if (rand() % 2 == 0)
1153 			isal_deflate_set_dict(stream, dict, dict_len);
1154 		else {
1155 			isal_deflate_process_dict(stream, &dict_str, dict, dict_len);
1156 			isal_deflate_reset_dict(stream, &dict_str);
1157 		}
1158 	}
1159 
1160 	while (1) {
1161 		loop_count++;
1162 
1163 		/* Setup in buffer for next round of compression */
1164 		if (stream->avail_in == 0) {
1165 			if (flush_type == NO_FLUSH || state->state == ZSTATE_NEW_HDR) {
1166 				/* Randomly choose size of the next out buffer */
1167 				in_size = rand() % (data_size + 1);
1168 
1169 				/* Limit size of buffer to be smaller than maximum */
1170 				if (in_size >= data_size - in_processed) {
1171 					in_size = data_size - in_processed;
1172 					stream->end_of_stream = 1;
1173 				}
1174 
1175 				if (in_size != 0) {
1176 					if (in_buf != NULL) {
1177 						free(in_buf);
1178 						in_buf = NULL;
1179 					}
1180 
1181 					in_buf = malloc(in_size);
1182 					if (in_buf == NULL) {
1183 						ret = MALLOC_FAILED;
1184 						break;
1185 					}
1186 					memcpy(in_buf, data + in_processed, in_size);
1187 					in_processed += in_size;
1188 
1189 					stream->avail_in = in_size;
1190 					stream->next_in = in_buf;
1191 				}
1192 			}
1193 		} else {
1194 			/* Randomly modify data after next in */
1195 			if (rand() % 4 == 0 && !no_mod) {
1196 
1197 				tmp_symbol = rand();
1198 				log_print
1199 				    ("Modifying data at index 0x%x from 0x%x to 0x%x before recalling isal_deflate\n",
1200 				     in_processed - stream->avail_in,
1201 				     data[in_processed - stream->avail_in], tmp_symbol);
1202 				*stream->next_in = tmp_symbol;
1203 				data[in_processed - stream->avail_in] = tmp_symbol;
1204 			}
1205 		}
1206 
1207 		/* Setup out buffer for next round of compression */
1208 		if (stream->avail_out == 0) {
1209 			/* Save compressed data inot compressed_buf */
1210 			if (out_buf != NULL) {
1211 				memcpy(compressed_buf + out_processed, out_buf,
1212 				       out_size - stream->avail_out);
1213 				out_processed += out_size - stream->avail_out;
1214 			}
1215 
1216 			/* Randomly choose size of the next out buffer */
1217 			out_size = rand() % (*compressed_size + 1);
1218 
1219 			/* Limit size of buffer to be smaller than maximum */
1220 			if (out_size > *compressed_size - out_processed)
1221 				out_size = *compressed_size - out_processed;
1222 
1223 			if (out_size != 0) {
1224 				if (out_buf != NULL) {
1225 					free(out_buf);
1226 					out_buf = NULL;
1227 				}
1228 
1229 				out_buf = malloc(out_size);
1230 				if (out_buf == NULL) {
1231 					ret = MALLOC_FAILED;
1232 					break;
1233 				}
1234 
1235 				stream->avail_out = out_size;
1236 				stream->next_out = out_buf;
1237 			}
1238 		}
1239 
1240 		if (state->state == ZSTATE_NEW_HDR) {
1241 			set_random_hufftable(stream, level, data, data_size);
1242 			if (stream->hufftables == hufftables_subset)
1243 				no_mod = 1;
1244 			else
1245 				no_mod = 0;
1246 		}
1247 
1248 		ret =
1249 		    isal_deflate_with_checks(stream, data_size, *compressed_size, in_buf,
1250 					     in_size, in_processed, out_buf, out_size,
1251 					     out_processed);
1252 
1253 		if (ret) {
1254 			if (ret == COMPRESS_OUT_BUFFER_OVERFLOW
1255 			    || ret == COMPRESS_INCORRECT_STATE)
1256 				memcpy(compressed_buf + out_processed, out_buf, out_size);
1257 			break;
1258 		}
1259 
1260 		/* Check if the compression is completed */
1261 		if (state->state == ZSTATE_END) {
1262 			memcpy(compressed_buf + out_processed, out_buf, out_size);
1263 			*compressed_size = stream->total_out;
1264 			break;
1265 		}
1266 
1267 	}
1268 
1269 	if (stream != NULL)
1270 		free(stream);
1271 	if (level_buf != NULL)
1272 		free(level_buf);
1273 	if (in_buf != NULL)
1274 		free(in_buf);
1275 	if (out_buf != NULL)
1276 		free(out_buf);
1277 
1278 	if (ret == COMPRESS_OUT_BUFFER_OVERFLOW && flush_type == SYNC_FLUSH
1279 	    && loop_count >= MAX_LOOPS)
1280 		ret = COMPRESS_LOOP_COUNT_OVERFLOW;
1281 
1282 	return ret;
1283 
1284 }
1285 
1286 /* Compress the input data into the outbuffer in one call to isal_deflate */
compress_single_pass(uint8_t * data,uint32_t data_size,uint8_t * compressed_buf,uint32_t * compressed_size,uint32_t flush_type,uint32_t gzip_flag,uint32_t level,uint8_t * dict,uint32_t dict_len,uint32_t hist_bits)1287 int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1288 			 uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
1289 			 uint32_t level, uint8_t * dict, uint32_t dict_len, uint32_t hist_bits)
1290 {
1291 	int ret = IGZIP_COMP_OK;
1292 	struct isal_zstream stream;
1293 	struct isal_zstate *state = &stream.internal_state;
1294 	uint32_t level_buf_size;
1295 	uint8_t *level_buf = NULL;
1296 	struct isal_hufftables *huff_tmp;
1297 	uint32_t reset_test_flag = 0;
1298 	struct isal_dict dict_str;
1299 
1300 	log_print("Starting Compress Single Pass\n");
1301 
1302 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1303 
1304 	isal_deflate_init(&stream);
1305 
1306 	set_random_hufftable(&stream, level, data, data_size);
1307 
1308 	if (state->state != ZSTATE_NEW_HDR)
1309 		return COMPRESS_INCORRECT_STATE;
1310 
1311 	if (rand() % 4 == 0) {
1312 		/* Test reset */
1313 		reset_test_flag = 1;
1314 		huff_tmp = stream.hufftables;
1315 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1316 
1317 		/* Restore variables not necessarily set by user */
1318 		stream.hufftables = huff_tmp;
1319 		stream.end_of_stream = 0;
1320 		stream.level = 0;
1321 		stream.level_buf = NULL;
1322 		stream.level_buf_size = 0;
1323 	}
1324 
1325 	stream.flush = flush_type;
1326 	stream.avail_in = data_size;
1327 	stream.next_in = data;
1328 	stream.avail_out = *compressed_size;
1329 	stream.next_out = compressed_buf;
1330 	stream.end_of_stream = 1;
1331 	stream.gzip_flag = gzip_flag;
1332 	stream.level = level;
1333 	stream.hist_bits = hist_bits;
1334 
1335 	if (level >= 1) {
1336 		level_buf_size = get_rand_level_buf_size(stream.level);
1337 		level_buf = malloc(level_buf_size);
1338 		create_rand_repeat_data(level_buf, level_buf_size);
1339 		stream.level_buf = level_buf;
1340 		stream.level_buf_size = level_buf_size;
1341 	}
1342 
1343 	if (reset_test_flag)
1344 		isal_deflate_reset(&stream);
1345 
1346 	if (dict != NULL) {
1347 		if (rand() % 2 == 0)
1348 			isal_deflate_set_dict(&stream, dict, dict_len);
1349 		else {
1350 			isal_deflate_process_dict(&stream, &dict_str, dict, dict_len);
1351 			isal_deflate_reset_dict(&stream, &dict_str);
1352 		}
1353 	}
1354 
1355 	ret =
1356 	    isal_deflate_with_checks(&stream, data_size, *compressed_size, data, data_size,
1357 				     data_size, compressed_buf, *compressed_size, 0);
1358 
1359 	if (level_buf != NULL)
1360 		free(level_buf);
1361 
1362 	/* Check if the compression is completed */
1363 	if (state->state == ZSTATE_END)
1364 		*compressed_size = stream.total_out;
1365 	else if (flush_type == SYNC_FLUSH && stream.avail_out < 16)
1366 		ret = COMPRESS_OUT_BUFFER_OVERFLOW;
1367 
1368 	return ret;
1369 
1370 }
1371 
1372 /* Compress the input data repeatedly into the outbuffer
1373  * Compresses and verifies in place to decrease memory usage
1374  */
compress_ver_rep_buf(uint8_t * data,uint32_t data_size,uint64_t data_rep_size,uint8_t * compressed_buf,uint32_t compressed_size,uint8_t * decomp_buf,uint32_t decomp_buf_size,uint32_t flush_type,uint32_t gzip_flag,uint32_t level)1375 int compress_ver_rep_buf(uint8_t * data, uint32_t data_size, uint64_t data_rep_size,
1376 			 uint8_t * compressed_buf, uint32_t compressed_size,
1377 			 uint8_t * decomp_buf, uint32_t decomp_buf_size, uint32_t flush_type,
1378 			 uint32_t gzip_flag, uint32_t level)
1379 {
1380 	int ret = IGZIP_COMP_OK;
1381 	struct isal_zstream stream;
1382 	struct inflate_state state;
1383 	uint32_t level_buf_size;
1384 	uint8_t *level_buf = NULL;
1385 	uint64_t data_remaining = data_rep_size;
1386 	uint64_t data_verified = 0;
1387 	uint32_t index;
1388 	uint32_t out_size, cmp_size;
1389 	uint32_t avail_out_start;
1390 
1391 	log_print("Starting Compress and Verify Repeated Buffer\n");
1392 
1393 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1394 
1395 	/* Setup compression stream */
1396 	isal_deflate_init(&stream);
1397 	stream.avail_in = 0;
1398 	stream.next_in = NULL;
1399 	stream.avail_out = 0;
1400 	stream.next_out = NULL;
1401 
1402 	set_random_hufftable(&stream, level, data, data_size);
1403 	stream.flush = flush_type;
1404 	stream.end_of_stream = 0;
1405 	stream.gzip_flag = gzip_flag;
1406 	stream.level = level;
1407 
1408 	if (level >= 1) {
1409 		level_buf_size = get_rand_level_buf_size(stream.level);
1410 		level_buf = malloc(level_buf_size);
1411 		create_rand_repeat_data(level_buf, level_buf_size);
1412 		stream.level_buf = level_buf;
1413 		stream.level_buf_size = level_buf_size;
1414 	}
1415 
1416 	/* Setup decompression stream */
1417 	create_rand_repeat_data((uint8_t *) & state, sizeof(state));
1418 	isal_inflate_init(&state);
1419 	state.crc_flag = gzip_flag;
1420 
1421 	while (data_remaining || stream.avail_in) {
1422 		/* Compress the input buffer */
1423 		if (stream.next_out == NULL) {
1424 			stream.avail_out = compressed_size;
1425 			stream.next_out = compressed_buf;
1426 		}
1427 
1428 		while (stream.avail_out > 0 && (data_remaining || stream.avail_in)) {
1429 			if (stream.avail_in == 0) {
1430 				stream.avail_in = data_size;
1431 				if (data_size >= data_remaining) {
1432 					stream.avail_in = data_remaining;
1433 					stream.end_of_stream = 1;
1434 				}
1435 
1436 				stream.next_in = data;
1437 				data_remaining -= stream.avail_in;
1438 			}
1439 
1440 			ret = isal_deflate(&stream);
1441 
1442 			if (ret)
1443 				return COMPRESS_GENERAL_ERROR;
1444 		}
1445 
1446 		/* Verfiy the compressed buffer */
1447 		state.next_in = compressed_buf;
1448 		state.avail_in = compressed_size;
1449 		state.next_out = NULL;
1450 		state.avail_out = 0;
1451 		create_rand_repeat_data(decomp_buf, decomp_buf_size);
1452 
1453 		while (state.avail_out == 0) {
1454 			state.next_out = decomp_buf;
1455 			state.avail_out = decomp_buf_size;
1456 
1457 			/* Force decoding to stop when avail_out rolls over */
1458 			if ((1ULL << 32) - state.total_out < decomp_buf_size)
1459 				state.avail_out = (1ULL << 32) - state.total_out;
1460 
1461 			avail_out_start = state.avail_out;
1462 
1463 			ret = isal_inflate(&state);
1464 			if (ret)
1465 				return inflate_ret_to_code(ret);
1466 
1467 			/* Check data accuracy */
1468 			index = data_verified % data_size;
1469 			out_size = avail_out_start - state.avail_out;
1470 			cmp_size =
1471 			    (out_size > data_size - index) ? data_size - index : out_size;
1472 			ret |= memcmp(decomp_buf, data + index, cmp_size);
1473 			out_size -= cmp_size;
1474 			cmp_size = (out_size > index) ? index : out_size;
1475 			ret |= memcmp(decomp_buf + data_size - index, data, cmp_size);
1476 			out_size -= cmp_size;
1477 			cmp_size = out_size;
1478 			ret |= memcmp(decomp_buf, decomp_buf + data_size, out_size);
1479 			if (ret)
1480 				return RESULT_ERROR;
1481 
1482 			data_verified += avail_out_start - state.avail_out;
1483 		}
1484 		stream.next_out = NULL;
1485 	}
1486 
1487 	if (level_buf != NULL)
1488 		free(level_buf);
1489 
1490 	return ret;
1491 
1492 }
1493 
1494 /* Statelessly compress the input buffer into the output buffer */
compress_stateless(uint8_t * data,uint32_t data_size,uint8_t * compressed_buf,uint32_t * compressed_size,uint32_t flush_type,uint32_t gzip_flag,uint32_t level,uint32_t hist_bits)1495 int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1496 		       uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
1497 		       uint32_t level, uint32_t hist_bits)
1498 {
1499 	int ret = IGZIP_COMP_OK;
1500 	struct isal_zstream stream;
1501 	uint32_t level_buf_size;
1502 	uint8_t *level_buf = NULL;
1503 	struct isal_hufftables *huff_tmp;
1504 	uint32_t reset_test_flag = 0;
1505 
1506 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1507 
1508 	isal_deflate_stateless_init(&stream);
1509 
1510 	set_random_hufftable(&stream, level, data, data_size);
1511 
1512 	if (rand() % 4 == 0) {
1513 		/* Test reset */
1514 		reset_test_flag = 1;
1515 		huff_tmp = stream.hufftables;
1516 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1517 
1518 		/* Restore variables not necessarily set by user */
1519 		stream.hufftables = huff_tmp;
1520 		stream.end_of_stream = 0;
1521 		stream.level = 0;
1522 		stream.level_buf = NULL;
1523 		stream.level_buf_size = 0;
1524 	}
1525 
1526 	stream.avail_in = data_size;
1527 	stream.next_in = data;
1528 	stream.flush = flush_type;
1529 	if (flush_type != NO_FLUSH)
1530 		stream.end_of_stream = 1;
1531 	stream.avail_out = *compressed_size;
1532 	stream.next_out = compressed_buf;
1533 	stream.gzip_flag = gzip_flag;
1534 	stream.level = level;
1535 	stream.hist_bits = hist_bits;
1536 
1537 	if (level == 1) {
1538 		/* This is to test case where level buf uses already existing
1539 		 * internal buffers */
1540 		level_buf_size = rand() % IBUF_SIZE;
1541 
1542 		if (level_buf_size >= ISAL_DEF_LVL1_MIN) {
1543 			level_buf = malloc(level_buf_size);
1544 			create_rand_repeat_data(level_buf, level_buf_size);
1545 			stream.level_buf = level_buf;
1546 			stream.level_buf_size = level_buf_size;
1547 		}
1548 	} else if (level > 1) {
1549 		level_buf_size = get_rand_level_buf_size(level);
1550 		level_buf = malloc(level_buf_size);
1551 		create_rand_repeat_data(level_buf, level_buf_size);
1552 		stream.level_buf = level_buf;
1553 		stream.level_buf_size = level_buf_size;
1554 	}
1555 
1556 	if (reset_test_flag)
1557 		isal_deflate_reset(&stream);
1558 
1559 	ret = isal_deflate_stateless(&stream);
1560 
1561 	if (level_buf != NULL)
1562 		free(level_buf);
1563 
1564 	/* verify the stream */
1565 	if (stream.next_in - data != stream.total_in ||
1566 	    stream.total_in + stream.avail_in != data_size)
1567 		return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR;
1568 
1569 	if (stream.next_out - compressed_buf != stream.total_out ||
1570 	    stream.total_out + stream.avail_out != *compressed_size) {
1571 		return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR;
1572 	}
1573 
1574 	if (ret != IGZIP_COMP_OK) {
1575 		if (ret == STATELESS_OVERFLOW)
1576 			return COMPRESS_OUT_BUFFER_OVERFLOW;
1577 		else if (ret == INVALID_FLUSH)
1578 			return INVALID_FLUSH_ERROR;
1579 		else {
1580 			printf("Return due to ret = %d with level = %d or %d\n", ret, level,
1581 			       stream.level);
1582 			return COMPRESS_GENERAL_ERROR;
1583 		}
1584 	}
1585 
1586 	if (!stream.end_of_stream) {
1587 		return COMPRESS_END_OF_STREAM_NOT_SET;
1588 	}
1589 
1590 	if (stream.avail_in != 0)
1591 		return COMPRESS_ALL_INPUT_FAIL;
1592 
1593 	*compressed_size = stream.total_out;
1594 
1595 	return ret;
1596 
1597 }
1598 
1599 /* Statelessly compress the input buffer into the output buffer */
compress_stateless_full_flush(uint8_t * data,uint32_t data_size,uint8_t * compressed_buf,uint32_t * compressed_size,uint32_t level,uint32_t hist_bits)1600 int compress_stateless_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1601 				  uint32_t * compressed_size, uint32_t level,
1602 				  uint32_t hist_bits)
1603 {
1604 	int ret = IGZIP_COMP_OK;
1605 	uint8_t *in_buf = NULL, *level_buf = NULL, *out_buf = compressed_buf;
1606 	uint32_t in_size = 0, level_buf_size;
1607 	uint32_t in_processed = 00;
1608 	struct isal_zstream stream;
1609 	uint32_t loop_count = 0;
1610 	struct isal_hufftables *huff_tmp;
1611 	uint32_t reset_test_flag = 0;
1612 
1613 	log_print("Starting Stateless Compress Full Flush\n");
1614 
1615 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1616 
1617 	isal_deflate_stateless_init(&stream);
1618 
1619 	if (rand() % 4 == 0) {
1620 		/* Test reset */
1621 		reset_test_flag = 1;
1622 		huff_tmp = stream.hufftables;
1623 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1624 
1625 		/* Restore variables not necessarily set by user */
1626 		stream.hufftables = huff_tmp;
1627 		stream.end_of_stream = 0;
1628 		stream.level = 0;
1629 		stream.level_buf = NULL;
1630 		stream.level_buf_size = 0;
1631 		stream.gzip_flag = 0;
1632 	}
1633 
1634 	stream.flush = FULL_FLUSH;
1635 	stream.end_of_stream = 0;
1636 	stream.avail_out = *compressed_size;
1637 	stream.next_out = compressed_buf;
1638 	stream.level = level;
1639 	stream.hist_bits = hist_bits;
1640 
1641 	if (level == 1) {
1642 		/* This is to test case where level_buf uses already existing
1643 		 * internal buffers */
1644 		level_buf_size = rand() % IBUF_SIZE;
1645 
1646 		if (level_buf_size >= ISAL_DEF_LVL1_MIN) {
1647 			level_buf = malloc(level_buf_size);
1648 			create_rand_repeat_data(level_buf, level_buf_size);
1649 			stream.level_buf = level_buf;
1650 			stream.level_buf_size = level_buf_size;
1651 		}
1652 	} else if (level > 1) {
1653 		level_buf_size = get_rand_level_buf_size(level);
1654 		level_buf = malloc(level_buf_size);
1655 		create_rand_repeat_data(level_buf, level_buf_size);
1656 		stream.level_buf = level_buf;
1657 		stream.level_buf_size = level_buf_size;
1658 	}
1659 
1660 	if (reset_test_flag)
1661 		isal_deflate_reset(&stream);
1662 
1663 	while (1) {
1664 		loop_count++;
1665 
1666 		/* Randomly choose size of the next out buffer */
1667 		in_size = rand() % (data_size + 1);
1668 
1669 		/* Limit size of buffer to be smaller than maximum */
1670 		if (in_size >= data_size - in_processed) {
1671 			in_size = data_size - in_processed;
1672 			stream.end_of_stream = 1;
1673 		}
1674 
1675 		stream.avail_in = in_size;
1676 
1677 		if (in_size != 0) {
1678 			if (in_buf != NULL) {
1679 				free(in_buf);
1680 				in_buf = NULL;
1681 			}
1682 
1683 			in_buf = malloc(in_size);
1684 			if (in_buf == NULL) {
1685 				ret = MALLOC_FAILED;
1686 				break;
1687 			}
1688 			memcpy(in_buf, data + in_processed, in_size);
1689 			in_processed += in_size;
1690 
1691 			stream.next_in = in_buf;
1692 		}
1693 
1694 		out_buf = stream.next_out;
1695 
1696 		if (stream.internal_state.state == ZSTATE_NEW_HDR)
1697 			set_random_hufftable(&stream, level, data, data_size);
1698 
1699 		ret = isal_deflate_stateless(&stream);
1700 
1701 		assert(stream.internal_state.bitbuf.m_bit_count == 0);
1702 
1703 		assert(compressed_buf == stream.next_out - stream.total_out);
1704 		if (ret)
1705 			break;
1706 
1707 		/* Verify that blocks are independent */
1708 		ret =
1709 		    inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size, 0, NULL,
1710 				  0, hist_bits);
1711 
1712 		if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE) {
1713 			break;
1714 		} else
1715 			ret = 0;
1716 
1717 		/* Check if the compression is completed */
1718 		if (in_processed == data_size) {
1719 			*compressed_size = stream.total_out;
1720 			break;
1721 		}
1722 
1723 	}
1724 
1725 	if (level_buf != NULL)
1726 		free(level_buf);
1727 
1728 	if (in_buf != NULL)
1729 		free(in_buf);
1730 
1731 	if (ret == STATELESS_OVERFLOW && loop_count >= MAX_LOOPS)
1732 		ret = COMPRESS_LOOP_COUNT_OVERFLOW;
1733 
1734 	return ret;
1735 
1736 }
1737 
1738 /* Compress the input data into the output buffer where the input buffer and
1739  * is randomly segmented to test for independence of blocks in full flush
1740  * compression*/
compress_full_flush(uint8_t * data,uint32_t data_size,uint8_t * compressed_buf,uint32_t * compressed_size,uint32_t gzip_flag,uint32_t level)1741 int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1742 			uint32_t * compressed_size, uint32_t gzip_flag, uint32_t level)
1743 {
1744 	int ret = IGZIP_COMP_OK;
1745 	uint8_t *in_buf = NULL, *out_buf = compressed_buf, *level_buf = NULL;
1746 	uint32_t in_size = 0, level_buf_size;
1747 	uint32_t in_processed = 00;
1748 	struct isal_zstream stream;
1749 	struct isal_zstate *state = &stream.internal_state;
1750 	uint32_t loop_count = 0;
1751 	struct isal_hufftables *huff_tmp;
1752 	uint32_t reset_test_flag = 0;
1753 
1754 	log_print("Starting Compress Full Flush\n");
1755 
1756 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1757 
1758 	isal_deflate_init(&stream);
1759 
1760 	if (state->state != ZSTATE_NEW_HDR)
1761 		return COMPRESS_INCORRECT_STATE;
1762 
1763 	if (rand() % 4 == 0) {
1764 		/* Test reset */
1765 		reset_test_flag = 1;
1766 		huff_tmp = stream.hufftables;
1767 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1768 
1769 		/* Restore variables not necessarily set by user */
1770 		stream.hufftables = huff_tmp;
1771 		stream.end_of_stream = 0;
1772 		stream.level = 0;
1773 		stream.level_buf = NULL;
1774 		stream.level_buf_size = 0;
1775 		stream.hist_bits = 0;
1776 	}
1777 
1778 	stream.flush = FULL_FLUSH;
1779 	stream.end_of_stream = 0;
1780 	stream.avail_out = *compressed_size;
1781 	stream.next_out = compressed_buf;
1782 	stream.total_out = 0;
1783 	stream.gzip_flag = gzip_flag;
1784 	stream.level = level;
1785 
1786 	if (level >= 1) {
1787 		level_buf_size = get_rand_level_buf_size(stream.level);
1788 		if (level_buf_size >= ISAL_DEF_LVL1_MIN) {
1789 			level_buf = malloc(level_buf_size);
1790 			create_rand_repeat_data(level_buf, level_buf_size);
1791 			stream.level_buf = level_buf;
1792 			stream.level_buf_size = level_buf_size;
1793 		}
1794 	}
1795 
1796 	if (reset_test_flag)
1797 		isal_deflate_reset(&stream);
1798 
1799 	while (1) {
1800 		loop_count++;
1801 
1802 		/* Setup in buffer for next round of compression */
1803 		if (state->state == ZSTATE_NEW_HDR) {
1804 			/* Randomly choose size of the next out buffer */
1805 			in_size = rand() % (data_size + 1);
1806 
1807 			/* Limit size of buffer to be smaller than maximum */
1808 			if (in_size >= data_size - in_processed) {
1809 				in_size = data_size - in_processed;
1810 				stream.end_of_stream = 1;
1811 			}
1812 
1813 			stream.avail_in = in_size;
1814 
1815 			if (in_size != 0) {
1816 				if (in_buf != NULL) {
1817 					free(in_buf);
1818 					in_buf = NULL;
1819 				}
1820 
1821 				in_buf = malloc(in_size);
1822 				if (in_buf == NULL) {
1823 					ret = MALLOC_FAILED;
1824 					break;
1825 				}
1826 				memcpy(in_buf, data + in_processed, in_size);
1827 				in_processed += in_size;
1828 
1829 				stream.next_in = in_buf;
1830 			}
1831 
1832 			out_buf = stream.next_out;
1833 		}
1834 
1835 		if (state->state == ZSTATE_NEW_HDR)
1836 			set_random_hufftable(&stream, level, data, data_size);
1837 
1838 		ret = isal_deflate(&stream);
1839 
1840 		if (ret)
1841 			break;
1842 
1843 		/* Verify that blocks are independent */
1844 		if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_END) {
1845 			ret =
1846 			    inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size,
1847 					  0, NULL, 0, 0);
1848 
1849 			if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE)
1850 				break;
1851 			else
1852 				ret = 0;
1853 		}
1854 
1855 		/* Check if the compression is completed */
1856 		if (state->state == ZSTATE_END) {
1857 			*compressed_size = stream.total_out;
1858 			break;
1859 		}
1860 
1861 	}
1862 
1863 	if (level_buf != NULL)
1864 		free(level_buf);
1865 
1866 	if (in_buf != NULL)
1867 		free(in_buf);
1868 
1869 	if (ret == COMPRESS_OUT_BUFFER_OVERFLOW && loop_count >= MAX_LOOPS)
1870 		ret = COMPRESS_LOOP_COUNT_OVERFLOW;
1871 
1872 	return ret;
1873 
1874 }
1875 
1876 /*Compress the input buffer into the output buffer, but switch the flush type in
1877  * the middle of the compression to test what happens*/
compress_swap_flush(uint8_t * data,uint32_t data_size,uint8_t * compressed_buf,uint32_t * compressed_size,uint32_t flush_type,int level,uint32_t gzip_flag)1878 int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1879 			uint32_t * compressed_size, uint32_t flush_type, int level,
1880 			uint32_t gzip_flag)
1881 {
1882 	int ret = IGZIP_COMP_OK;
1883 	struct isal_zstream stream;
1884 	struct isal_zstate *state = &stream.internal_state;
1885 	uint32_t partial_size;
1886 	struct isal_hufftables *huff_tmp;
1887 	uint32_t reset_test_flag = 0;
1888 	uint32_t level_buf_size;
1889 	uint8_t *level_buf = NULL;
1890 
1891 	log_print("Starting Compress Swap Flush\n");
1892 
1893 	isal_deflate_init(&stream);
1894 
1895 	set_random_hufftable(&stream, 0, data, data_size);
1896 
1897 	if (state->state != ZSTATE_NEW_HDR)
1898 		return COMPRESS_INCORRECT_STATE;
1899 
1900 	if (rand() % 4 == 0) {
1901 		/* Test reset */
1902 		reset_test_flag = 1;
1903 		huff_tmp = stream.hufftables;
1904 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1905 
1906 		/* Restore variables not necessarily set by user */
1907 		stream.hufftables = huff_tmp;
1908 		stream.end_of_stream = 0;
1909 		stream.level = 0;
1910 		stream.level_buf = NULL;
1911 		stream.level_buf_size = 0;
1912 	}
1913 
1914 	partial_size = rand() % (data_size + 1);
1915 
1916 	stream.flush = flush_type;
1917 	stream.avail_in = partial_size;
1918 	stream.next_in = data;
1919 	stream.avail_out = *compressed_size;
1920 	stream.next_out = compressed_buf;
1921 	stream.end_of_stream = 0;
1922 	stream.gzip_flag = gzip_flag;
1923 	if (level) {
1924 		stream.level = level;
1925 		level_buf_size = get_rand_level_buf_size(stream.level);
1926 		level_buf = malloc(level_buf_size);
1927 		create_rand_repeat_data(level_buf, level_buf_size);
1928 		stream.level_buf = level_buf;
1929 		stream.level_buf_size = level_buf_size;
1930 	}
1931 
1932 	if (reset_test_flag)
1933 		isal_deflate_reset(&stream);
1934 
1935 	ret =
1936 	    isal_deflate_with_checks(&stream, data_size, *compressed_size, data, partial_size,
1937 				     partial_size, compressed_buf, *compressed_size, 0);
1938 
1939 	if (ret)
1940 		return ret;
1941 
1942 	if (state->state == ZSTATE_NEW_HDR)
1943 		set_random_hufftable(&stream, 0, data, data_size);
1944 
1945 	flush_type = rand() % 3;
1946 
1947 	stream.flush = flush_type;
1948 	stream.avail_in = data_size - partial_size;
1949 	stream.next_in = data + partial_size;
1950 	stream.end_of_stream = 1;
1951 
1952 	ret =
1953 	    isal_deflate_with_checks(&stream, data_size, *compressed_size, data + partial_size,
1954 				     data_size - partial_size, data_size, compressed_buf,
1955 				     *compressed_size, 0);
1956 
1957 	if (ret == COMPRESS_GENERAL_ERROR)
1958 		return INVALID_FLUSH_ERROR;
1959 
1960 	*compressed_size = stream.total_out;
1961 
1962 	if (stream.level_buf != NULL)
1963 		free(stream.level_buf);
1964 
1965 	return ret;
1966 }
1967 
1968 /* Test deflate_stateless */
test_compress_stateless(uint8_t * in_data,uint32_t in_size,uint32_t flush_type)1969 int test_compress_stateless(uint8_t * in_data, uint32_t in_size, uint32_t flush_type)
1970 {
1971 	int ret = IGZIP_COMP_OK;
1972 	uint32_t z_size, overflow, gzip_flag, level, hist_bits;
1973 	uint8_t *z_buf = NULL;
1974 	uint8_t *in_buf = NULL;
1975 
1976 	gzip_flag = rand() % 5;
1977 	hist_bits = rand() % 16;
1978 	level = get_rand_level();
1979 
1980 	if (in_size != 0) {
1981 		in_buf = malloc(in_size);
1982 
1983 		if (in_buf == NULL)
1984 			return MALLOC_FAILED;
1985 
1986 		memcpy(in_buf, in_data, in_size);
1987 	}
1988 
1989 	/* Test non-overflow case where a type 0 block is not written */
1990 	z_size = 2 * in_size + hdr_bytes;
1991 	if (gzip_flag == IGZIP_GZIP)
1992 		z_size += gzip_extra_bytes;
1993 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
1994 		z_size += gzip_trl_bytes;
1995 	else if (gzip_flag == IGZIP_ZLIB)
1996 		z_size += zlib_extra_bytes;
1997 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
1998 		z_size += zlib_trl_bytes;
1999 
2000 	z_buf = malloc(z_size);
2001 
2002 	if (z_buf == NULL)
2003 		return MALLOC_FAILED;
2004 
2005 	create_rand_repeat_data(z_buf, z_size);
2006 
2007 	/* If flush type is invalid */
2008 	if (flush_type != NO_FLUSH && flush_type != FULL_FLUSH) {
2009 		ret =
2010 		    compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag,
2011 				       level, hist_bits);
2012 
2013 		if (ret != INVALID_FLUSH_ERROR)
2014 			print_error(ret);
2015 		else
2016 			ret = 0;
2017 
2018 		if (z_buf != NULL)
2019 			free(z_buf);
2020 
2021 		if (in_buf != NULL)
2022 			free(in_buf);
2023 
2024 		return ret;
2025 	}
2026 
2027 	/* Else test valid flush type */
2028 	ret = compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level,
2029 				 hist_bits);
2030 
2031 	if (!ret)
2032 		ret =
2033 		    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0,
2034 				  hist_bits);
2035 
2036 	if (options.verbose && ret) {
2037 		log_print
2038 		    ("Compressed array at level %d with gzip flag %d, flush type %d, and window bits %d: ",
2039 		     level, gzip_flag, flush_type, hist_bits);
2040 		log_uint8_t(z_buf, z_size);
2041 		log_print("\n");
2042 		log_print("Data: ");
2043 		log_uint8_t(in_buf, in_size);
2044 	}
2045 
2046 	if (z_buf != NULL) {
2047 		free(z_buf);
2048 		z_buf = NULL;
2049 	}
2050 
2051 	print_error(ret);
2052 	if (ret)
2053 		return ret;
2054 
2055 	/*Test non-overflow case where a type 0 block is possible to be written */
2056 	z_size = TYPE0_HDR_SIZE * ((in_size + TYPE0_MAX_SIZE - 1) / TYPE0_MAX_SIZE) + in_size;
2057 
2058 	if (gzip_flag == IGZIP_GZIP)
2059 		z_size += gzip_extra_bytes;
2060 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
2061 		z_size += gzip_trl_bytes;
2062 	else if (gzip_flag == IGZIP_ZLIB)
2063 		z_size += zlib_extra_bytes;
2064 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
2065 		z_size += zlib_trl_bytes;
2066 
2067 	if (z_size <= gzip_extra_bytes)
2068 		z_size += TYPE0_HDR_SIZE;
2069 
2070 	if (z_size < 8)
2071 		z_size = 8;
2072 
2073 	z_buf = malloc(z_size);
2074 
2075 	if (z_buf == NULL)
2076 		return MALLOC_FAILED;
2077 
2078 	create_rand_repeat_data(z_buf, z_size);
2079 
2080 	ret = compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level,
2081 				 hist_bits);
2082 	if (!ret)
2083 		ret =
2084 		    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0,
2085 				  hist_bits);
2086 	if (ret) {
2087 		log_print
2088 		    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2089 		     level, gzip_flag, flush_type, hist_bits);
2090 		log_uint8_t(z_buf, z_size);
2091 		log_print("\n");
2092 		log_print("Data: ");
2093 		log_uint8_t(in_buf, in_size);
2094 	}
2095 
2096 	if (!ret) {
2097 		free(z_buf);
2098 		z_buf = NULL;
2099 
2100 		/* Test random overflow case */
2101 		z_size = rand() % z_size;
2102 
2103 		if (z_size > in_size)
2104 			z_size = rand() & in_size;
2105 
2106 		if (z_size > 0) {
2107 			z_buf = malloc(z_size);
2108 
2109 			if (z_buf == NULL)
2110 				return MALLOC_FAILED;
2111 		}
2112 
2113 		overflow = compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type,
2114 					      gzip_flag, level, hist_bits);
2115 
2116 		if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
2117 			if (overflow == 0)
2118 				ret =
2119 				    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag,
2120 						  NULL, 0, hist_bits);
2121 
2122 			if (overflow != 0 || ret != 0) {
2123 				log_print("overflow error = %d\n", overflow);
2124 				log_error(overflow);
2125 				log_print("inflate ret = %d\n", ret);
2126 				log_error(ret);
2127 
2128 				log_print
2129 				    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2130 				     level, gzip_flag, flush_type, hist_bits);
2131 
2132 				log_uint8_t(z_buf, z_size);
2133 				log_print("\n");
2134 				log_print("Data: ");
2135 				log_uint8_t(in_buf, in_size);
2136 
2137 				printf("Failed on compress single pass overflow\n");
2138 				print_error(ret);
2139 				ret = OVERFLOW_TEST_ERROR;
2140 			}
2141 		}
2142 	}
2143 
2144 	print_error(ret);
2145 	if (ret) {
2146 		if (z_buf != NULL) {
2147 			free(z_buf);
2148 			z_buf = NULL;
2149 		}
2150 		if (in_buf != NULL)
2151 			free(in_buf);
2152 		return ret;
2153 	}
2154 
2155 	if (flush_type == FULL_FLUSH) {
2156 		if (z_buf != NULL)
2157 			free(z_buf);
2158 
2159 		z_size = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5);
2160 
2161 		z_buf = malloc(z_size);
2162 
2163 		if (z_buf == NULL)
2164 			return MALLOC_FAILED;
2165 
2166 		create_rand_repeat_data(z_buf, z_size);
2167 
2168 		/* Else test valid flush type */
2169 		ret = compress_stateless_full_flush(in_buf, in_size, z_buf, &z_size,
2170 						    level, hist_bits);
2171 
2172 		if (!ret)
2173 			ret =
2174 			    inflate_check(z_buf, z_size, in_buf, in_size, 0, NULL, 0,
2175 					  hist_bits);
2176 		else if (ret == COMPRESS_LOOP_COUNT_OVERFLOW)
2177 			ret = 0;
2178 
2179 		print_error(ret);
2180 
2181 		if (ret) {
2182 			log_print
2183 			    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2184 			     level, gzip_flag, FULL_FLUSH, hist_bits);
2185 			log_uint8_t(z_buf, z_size);
2186 			log_print("\n");
2187 			log_print("Data: ");
2188 			log_uint8_t(in_buf, in_size);
2189 		}
2190 	}
2191 	if (z_buf != NULL)
2192 		free(z_buf);
2193 
2194 	if (in_buf != NULL)
2195 		free(in_buf);
2196 
2197 	return ret;
2198 }
2199 
2200 /* Test deflate */
test_compress(uint8_t * in_buf,uint32_t in_size,uint32_t flush_type)2201 int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
2202 {
2203 	int ret = IGZIP_COMP_OK, fin_ret = IGZIP_COMP_OK;
2204 	uint32_t overflow = 0, gzip_flag, level, hist_bits;
2205 	uint32_t z_size = 0, z_size_max = 0, z_compressed_size, dict_len = 0;
2206 	uint8_t *z_buf = NULL, *dict = NULL;
2207 
2208 	/* Test a non overflow case */
2209 	if (flush_type == NO_FLUSH)
2210 		z_size_max = 2 * in_size + hdr_bytes + 2;
2211 	else if (flush_type == SYNC_FLUSH || flush_type == FULL_FLUSH)
2212 		z_size_max = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5);
2213 	else {
2214 		printf("Invalid Flush Parameter\n");
2215 		return COMPRESS_GENERAL_ERROR;
2216 	}
2217 
2218 	gzip_flag = rand() % 5;
2219 	hist_bits = rand() % 16;
2220 	level = get_rand_level();
2221 
2222 	z_size = z_size_max;
2223 
2224 	if (gzip_flag == IGZIP_GZIP)
2225 		z_size += gzip_extra_bytes;
2226 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
2227 		z_size += gzip_trl_bytes;
2228 	else if (gzip_flag == IGZIP_ZLIB)
2229 		z_size += zlib_extra_bytes;
2230 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
2231 		z_size += zlib_trl_bytes;
2232 
2233 	z_buf = malloc(z_size);
2234 	if (z_buf == NULL) {
2235 		print_error(MALLOC_FAILED);
2236 		return MALLOC_FAILED;
2237 	}
2238 	create_rand_repeat_data(z_buf, z_size);
2239 
2240 	if (rand() % 8 == 0) {
2241 		dict_len = (rand() % IGZIP_HIST_SIZE) + 1;
2242 		dict = malloc(dict_len);
2243 		if (dict == NULL) {
2244 			print_error(MALLOC_FAILED);
2245 			return MALLOC_FAILED;
2246 		}
2247 		create_rand_dict(dict, dict_len, z_buf, z_size);
2248 	}
2249 
2250 	ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
2251 				   gzip_flag, level, dict, dict_len, hist_bits);
2252 
2253 	if (!ret)
2254 		ret =
2255 		    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict, dict_len,
2256 				  hist_bits);
2257 
2258 	if (ret) {
2259 		log_print
2260 		    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2261 		     level, gzip_flag, flush_type, hist_bits);
2262 		log_uint8_t(z_buf, z_size);
2263 		log_print("\n");
2264 		if (dict != NULL) {
2265 			log_print("Using Dictionary: ");
2266 			log_uint8_t(dict, dict_len);
2267 			log_print("\n");
2268 		}
2269 		log_print("Data: ");
2270 		log_uint8_t(in_buf, in_size);
2271 
2272 		printf("Failed on compress single pass\n");
2273 		print_error(ret);
2274 	}
2275 
2276 	if (dict != NULL) {
2277 		free(dict);
2278 		dict = NULL;
2279 		dict_len = 0;
2280 	}
2281 
2282 	fin_ret |= ret;
2283 	if (ret)
2284 		goto test_compress_cleanup;
2285 
2286 	z_compressed_size = z_size;
2287 	z_size = z_size_max;
2288 	create_rand_repeat_data(z_buf, z_size_max);
2289 
2290 	if (rand() % 8 == 0) {
2291 		dict_len = (rand() % IGZIP_HIST_SIZE) + 1;
2292 		dict = malloc(dict_len);
2293 		if (dict == NULL) {
2294 			print_error(MALLOC_FAILED);
2295 			return MALLOC_FAILED;
2296 		}
2297 		create_rand_dict(dict, dict_len, z_buf, z_size);
2298 	}
2299 
2300 	ret =
2301 	    compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level,
2302 				dict, dict_len, hist_bits);
2303 
2304 	if (!ret)
2305 		ret =
2306 		    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict, dict_len,
2307 				  hist_bits);
2308 
2309 	if (ret) {
2310 		log_print
2311 		    ("Compressed array at level %d with gzip flag %d, flush type %d and hist_bits %d: ",
2312 		     level, gzip_flag, flush_type, hist_bits);
2313 		log_uint8_t(z_buf, z_size);
2314 		log_print("\n");
2315 		if (dict != NULL) {
2316 			log_print("Using Dictionary: ");
2317 			log_uint8_t(dict, dict_len);
2318 			log_print("\n");
2319 		}
2320 		log_print("Data: ");
2321 		log_uint8_t(in_buf, in_size);
2322 
2323 		printf("Failed on compress multi pass\n");
2324 		print_error(ret);
2325 	}
2326 
2327 	if (dict != NULL) {
2328 		free(dict);
2329 		dict = NULL;
2330 		dict_len = 0;
2331 	}
2332 
2333 	fin_ret |= ret;
2334 	if (ret)
2335 		goto test_compress_cleanup;
2336 
2337 	ret = 0;
2338 
2339 	/* Test random overflow case */
2340 	if (flush_type == SYNC_FLUSH && z_compressed_size > in_size)
2341 		z_compressed_size = in_size + 1;
2342 
2343 	z_size = rand() % z_compressed_size;
2344 	create_rand_repeat_data(z_buf, z_size);
2345 
2346 	overflow = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
2347 					gzip_flag, level, dict, dict_len, hist_bits);
2348 
2349 	if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
2350 		if (overflow == 0)
2351 			ret =
2352 			    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict,
2353 					  dict_len, hist_bits);
2354 
2355 		/* Rarely single pass overflow will compresses data
2356 		 * better than the initial run. This is to stop that
2357 		 * case from erroring. */
2358 		if (overflow != 0 || ret != 0) {
2359 			log_print("overflow error = %d\n", overflow);
2360 			log_error(overflow);
2361 			log_print("inflate ret = %d\n", ret);
2362 			log_error(ret);
2363 
2364 			log_print
2365 			    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2366 			     level, gzip_flag, flush_type, hist_bits);
2367 			log_uint8_t(z_buf, z_size);
2368 			log_print("\n");
2369 			log_print("Data: ");
2370 			log_uint8_t(in_buf, in_size);
2371 
2372 			printf("Failed on compress single pass overflow\n");
2373 			print_error(ret);
2374 			ret = OVERFLOW_TEST_ERROR;
2375 		}
2376 	}
2377 
2378 	fin_ret |= ret;
2379 	if (ret)
2380 		goto test_compress_cleanup;
2381 
2382 	if (flush_type == NO_FLUSH) {
2383 		create_rand_repeat_data(z_buf, z_size);
2384 
2385 		overflow =
2386 		    compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type,
2387 					gzip_flag, level, dict, dict_len, hist_bits);
2388 
2389 		if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
2390 			if (overflow == 0)
2391 				ret =
2392 				    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag,
2393 						  dict, dict_len, hist_bits);
2394 
2395 			/* Rarely multi pass overflow will compresses data
2396 			 * better than the initial run. This is to stop that
2397 			 * case from erroring */
2398 			if (overflow != 0 || ret != 0) {
2399 				log_print("overflow error = %d\n", overflow);
2400 				log_error(overflow);
2401 				log_print("inflate ret = %d\n", ret);
2402 				log_error(ret);
2403 				log_print
2404 				    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2405 				     level, gzip_flag, flush_type, hist_bits);
2406 				log_uint8_t(z_buf, z_size);
2407 				log_print("\n");
2408 				log_print("Data: ");
2409 				log_uint8_t(in_buf, in_size);
2410 
2411 				printf("Failed on compress multi pass overflow\n");
2412 				print_error(ret);
2413 				ret = OVERFLOW_TEST_ERROR;
2414 			}
2415 		}
2416 		fin_ret |= ret;
2417 	}
2418 
2419       test_compress_cleanup:
2420 	free(z_buf);
2421 
2422 	return fin_ret;
2423 }
2424 
2425 /* Test swapping flush types in the middle of compression */
test_flush(uint8_t * in_buf,uint32_t in_size)2426 int test_flush(uint8_t * in_buf, uint32_t in_size)
2427 {
2428 	int fin_ret = IGZIP_COMP_OK, ret;
2429 	uint32_t z_size, flush_type = 0, gzip_flag, level;
2430 	uint8_t *z_buf = NULL;
2431 
2432 	gzip_flag = rand() % 5;
2433 	level = get_rand_level();
2434 
2435 	z_size = 2 * in_size + 2 * hdr_bytes + 8;
2436 	if (gzip_flag == IGZIP_GZIP)
2437 		z_size += gzip_extra_bytes;
2438 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
2439 		z_size += gzip_trl_bytes;
2440 	else if (gzip_flag == IGZIP_ZLIB)
2441 		z_size += zlib_extra_bytes;
2442 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
2443 		z_size += zlib_trl_bytes;
2444 
2445 	z_buf = malloc(z_size);
2446 
2447 	if (z_buf == NULL)
2448 		return MALLOC_FAILED;
2449 
2450 	create_rand_repeat_data(z_buf, z_size);
2451 
2452 	while (flush_type < 3)
2453 		flush_type = rand() & 0xFFFF;
2454 
2455 	/* Test invalid flush */
2456 	ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
2457 				   gzip_flag, level, NULL, 0, 0);
2458 
2459 	if (ret == COMPRESS_GENERAL_ERROR)
2460 		ret = 0;
2461 	else {
2462 		printf("Failed when passing invalid flush parameter\n");
2463 		ret = INVALID_FLUSH_ERROR;
2464 	}
2465 
2466 	fin_ret |= ret;
2467 	print_error(ret);
2468 
2469 	create_rand_repeat_data(z_buf, z_size);
2470 
2471 	/* Test swapping flush type */
2472 	ret =
2473 	    compress_swap_flush(in_buf, in_size, z_buf, &z_size, rand() % 3, level, gzip_flag);
2474 
2475 	if (!ret)
2476 		ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0, 0);
2477 
2478 	if (ret) {
2479 		log_print("Compressed array at level %d with gzip flag %d: ", level,
2480 			  gzip_flag);
2481 		log_uint8_t(z_buf, z_size);
2482 		log_print("\n");
2483 		log_print("Data: ");
2484 		log_uint8_t(in_buf, in_size);
2485 
2486 		printf("Failed on swapping flush type\n");
2487 		print_error(ret);
2488 	}
2489 
2490 	fin_ret |= ret;
2491 	print_error(ret);
2492 
2493 	return fin_ret;
2494 }
2495 
2496 /* Test there are no length distance pairs across full flushes */
test_full_flush(uint8_t * in_buf,uint32_t in_size)2497 int test_full_flush(uint8_t * in_buf, uint32_t in_size)
2498 {
2499 	int ret = IGZIP_COMP_OK;
2500 	uint32_t z_size, gzip_flag, level;
2501 	uint8_t *z_buf = NULL;
2502 
2503 	gzip_flag = rand() % 5;
2504 	level = get_rand_level();
2505 	z_size = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5);
2506 
2507 	if (gzip_flag == IGZIP_GZIP)
2508 		z_size += gzip_extra_bytes;
2509 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
2510 		z_size += gzip_trl_bytes;
2511 	else if (gzip_flag == IGZIP_ZLIB)
2512 		z_size += zlib_extra_bytes;
2513 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
2514 		z_size += zlib_trl_bytes;
2515 
2516 	z_buf = malloc(z_size);
2517 	if (z_buf == NULL) {
2518 		print_error(MALLOC_FAILED);
2519 		return MALLOC_FAILED;
2520 	}
2521 
2522 	create_rand_repeat_data(z_buf, z_size);
2523 
2524 	ret = compress_full_flush(in_buf, in_size, z_buf, &z_size, gzip_flag, level);
2525 
2526 	if (!ret)
2527 		ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0, 0);
2528 
2529 	if (ret) {
2530 		log_print("Compressed array at level %d with gzip flag %d and flush type %d: ",
2531 			  level, gzip_flag, FULL_FLUSH);
2532 		log_uint8_t(z_buf, z_size);
2533 		log_print("\n");
2534 		log_print("Data: ");
2535 		log_uint8_t(in_buf, in_size);
2536 
2537 		printf("Failed on compress multi pass\n");
2538 		print_error(ret);
2539 	}
2540 
2541 	free(z_buf);
2542 
2543 	return ret;
2544 }
2545 
test_inflate(struct vect_result * in_vector)2546 int test_inflate(struct vect_result *in_vector)
2547 {
2548 	int ret = IGZIP_COMP_OK;
2549 	uint8_t *compress_buf = in_vector->vector, *out_buf = NULL;
2550 	uint64_t compress_len = in_vector->vector_length;
2551 	uint32_t out_size = 0;
2552 
2553 	out_size = 10 * in_vector->vector_length;
2554 	out_buf = malloc(out_size);
2555 	if (out_buf == NULL)
2556 		return MALLOC_FAILED;
2557 
2558 	ret = inflate_stateless_pass(compress_buf, compress_len, out_buf, &out_size, 0);
2559 
2560 	if (ret == INFLATE_LEFTOVER_INPUT)
2561 		ret = ISAL_DECOMP_OK;
2562 
2563 	if (ret != in_vector->expected_error)
2564 		printf("Inflate return value incorrect, %d != %d\n", ret,
2565 		       in_vector->expected_error);
2566 	else
2567 		ret = IGZIP_COMP_OK;
2568 
2569 	if (!ret) {
2570 		ret = inflate_multi_pass(compress_buf, compress_len, out_buf, &out_size,
2571 					 0, NULL, 0, 0);
2572 
2573 		if (ret == INFLATE_LEFTOVER_INPUT)
2574 			ret = ISAL_DECOMP_OK;
2575 
2576 		if (ret != in_vector->expected_error)
2577 			printf("Inflate return value incorrect, %d != %d\n", ret,
2578 			       in_vector->expected_error);
2579 		else
2580 			ret = IGZIP_COMP_OK;
2581 	}
2582 
2583 	return ret;
2584 
2585 }
2586 
test_large(uint8_t * in_buf,uint32_t in_size,uint64_t large_size)2587 int test_large(uint8_t * in_buf, uint32_t in_size, uint64_t large_size)
2588 {
2589 
2590 	int ret = IGZIP_COMP_OK;
2591 	uint32_t gzip_flag, level;
2592 	uint32_t z_size = 0, z_size_max = 0, tmp_buf_size;
2593 	uint8_t *z_buf = NULL, *tmp_buf = NULL;
2594 	int flush_type = NO_FLUSH;
2595 
2596 	/* Test a non overflow case */
2597 	z_size_max = MAX_LARGE_COMP_BUF_SIZE;
2598 
2599 	gzip_flag = rand() % 5;
2600 	level = get_rand_level();
2601 
2602 	z_size = z_size_max;
2603 	z_buf = malloc(z_size);
2604 	if (z_buf == NULL) {
2605 		print_error(MALLOC_FAILED);
2606 		return MALLOC_FAILED;
2607 	}
2608 	create_rand_repeat_data(z_buf, z_size);
2609 
2610 	tmp_buf_size = IBUF_SIZE;
2611 	tmp_buf = malloc(tmp_buf_size);
2612 	if (tmp_buf == NULL) {
2613 		print_error(MALLOC_FAILED);
2614 		return MALLOC_FAILED;
2615 	}
2616 
2617 	ret =
2618 	    compress_ver_rep_buf(in_buf, in_size, large_size, z_buf, z_size, tmp_buf,
2619 				 tmp_buf_size, flush_type, gzip_flag, level);
2620 
2621 	if (ret)
2622 		print_error(ret);
2623 
2624 	if (z_buf != NULL) {
2625 		free(z_buf);
2626 		z_buf = NULL;
2627 	}
2628 
2629 	if (tmp_buf != NULL) {
2630 		free(tmp_buf);
2631 		tmp_buf = NULL;
2632 	}
2633 
2634 	return ret;
2635 }
2636 
2637 /* Run multiple compression tests on data stored in a file */
test_compress_file(char * file_name)2638 int test_compress_file(char *file_name)
2639 {
2640 	int ret = IGZIP_COMP_OK;
2641 	uint64_t in_size;
2642 	uint8_t *in_buf = NULL;
2643 	FILE *in_file = NULL;
2644 
2645 	in_file = fopen(file_name, "rb");
2646 	if (!in_file) {
2647 		printf("Failed to open file %s\n", file_name);
2648 		return FILE_READ_FAILED;
2649 	}
2650 
2651 	in_size = get_filesize(in_file);
2652 	if (in_size > MAX_FILE_SIZE)
2653 		in_size = MAX_FILE_SIZE;
2654 
2655 	if (in_size != 0) {
2656 		in_buf = malloc(in_size);
2657 		if (in_buf == NULL) {
2658 			printf("Failed to allocate in_buf for test_compress_file\n");
2659 			return MALLOC_FAILED;
2660 		}
2661 		if (fread(in_buf, 1, in_size, in_file) != in_size) {
2662 			printf("Failed to read in_buf from test_compress_file\n");
2663 			free(in_buf);
2664 			return FILE_READ_FAILED;
2665 		}
2666 	}
2667 
2668 	ret |= test_compress_stateless(in_buf, in_size, NO_FLUSH);
2669 	if (!ret)
2670 		ret |= test_compress_stateless(in_buf, in_size, SYNC_FLUSH);
2671 	if (!ret)
2672 		ret |= test_compress_stateless(in_buf, in_size, FULL_FLUSH);
2673 	if (!ret)
2674 		ret |= test_compress(in_buf, in_size, NO_FLUSH);
2675 	if (!ret)
2676 		ret |= test_compress(in_buf, in_size, SYNC_FLUSH);
2677 	if (!ret)
2678 		ret |= test_compress(in_buf, in_size, FULL_FLUSH);
2679 	if (!ret)
2680 		ret |= test_flush(in_buf, in_size);
2681 
2682 	if (ret)
2683 		printf("Failed on file %s\n", file_name);
2684 
2685 	if (in_buf != NULL)
2686 		free(in_buf);
2687 
2688 	return ret;
2689 }
2690 
create_custom_hufftables(struct isal_hufftables * hufftables_custom,int file_count,char * files[])2691 int create_custom_hufftables(struct isal_hufftables *hufftables_custom, int file_count,
2692 			     char *files[])
2693 {
2694 	long int file_length;
2695 	uint8_t *stream = NULL;
2696 	struct isal_huff_histogram histogram;
2697 	FILE *file;
2698 	int i;
2699 
2700 	memset(&histogram, 0, sizeof(histogram));
2701 
2702 	for (i = 0; i < file_count; i++) {
2703 		printf("Processing %s\n", files[i]);
2704 		file = fopen(files[i], "r");
2705 		if (file == NULL) {
2706 			printf("Error opening file\n");
2707 			return 1;
2708 		}
2709 		fseek(file, 0, SEEK_END);
2710 		file_length = ftell(file);
2711 		fseek(file, 0, SEEK_SET);
2712 		file_length -= ftell(file);
2713 
2714 		if (file_length > 0) {
2715 			stream = malloc(file_length);
2716 			if (stream == NULL) {
2717 				printf("Failed to allocate memory to read in file\n");
2718 				fclose(file);
2719 				return 1;
2720 			}
2721 		}
2722 
2723 		if (fread(stream, 1, file_length, file) != file_length) {
2724 			printf("Error occurred when reading file\n");
2725 			fclose(file);
2726 			free(stream);
2727 			stream = NULL;
2728 			return 1;
2729 		}
2730 
2731 		/* Create a histogram of frequency of symbols found in stream to
2732 		 * generate the huffman tree.*/
2733 		isal_update_histogram(stream, file_length, &histogram);
2734 
2735 		fclose(file);
2736 		if (stream != NULL) {
2737 			free(stream);
2738 			stream = NULL;
2739 		}
2740 	}
2741 
2742 	return isal_create_hufftables(hufftables_custom, &histogram);
2743 
2744 }
2745 
main(int argc,char * argv[])2746 int main(int argc, char *argv[])
2747 {
2748 	int i = 0, j = 0, ret = 0, fin_ret = 0;
2749 	uint32_t in_size = 0, offset = 0;
2750 	uint8_t *in_buf;
2751 	struct isal_hufftables hufftables_custom, hufftables_sub;
2752 	uint64_t iterations, large_buf_size;
2753 	size_t argv_index;
2754 	char **input_files;
2755 	size_t file_count;
2756 
2757 	argv_index = parse_options(argc, argv);
2758 
2759 	input_files = &argv[argv_index];
2760 	file_count = argc - argv_index;
2761 
2762 	if (options.verbose)
2763 		setbuf(stdout, NULL);
2764 
2765 	printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024);
2766 	printf("Test Seed  : %d\n", options.test_seed);
2767 	printf("Randoms    : %d\n", options.randoms);
2768 	srand(options.test_seed);
2769 
2770 	hufftables_subset = &hufftables_sub;
2771 	if (file_count > 0) {
2772 		ret = create_custom_hufftables(&hufftables_custom, file_count, input_files);
2773 		if (ret == 0)
2774 			hufftables = &hufftables_custom;
2775 		else {
2776 			printf("Failed to generate custom hufftable");
2777 			return -1;
2778 		}
2779 	}
2780 
2781 	in_buf = malloc(IBUF_SIZE);
2782 	memset(in_buf, 0, IBUF_SIZE);
2783 
2784 	if (in_buf == NULL) {
2785 		fprintf(stderr, "Can't allocate in_buf memory\n");
2786 		return -1;
2787 	}
2788 
2789 	if (file_count > 0) {
2790 		printf("igzip_rand_test files:                  ");
2791 
2792 		for (i = 0; i < file_count; i++) {
2793 			ret |= test_compress_file(input_files[i]);
2794 			if (ret)
2795 				return ret;
2796 		}
2797 
2798 		printf("................");
2799 		printf("%s\n", ret ? "Fail" : "Pass");
2800 		fin_ret |= ret;
2801 	}
2802 
2803 	printf("igzip_rand_test stateless:              ");
2804 
2805 	ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), NO_FLUSH);
2806 	if (ret)
2807 		return ret;
2808 
2809 	ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), NO_FLUSH);
2810 	if (ret)
2811 		return ret;
2812 
2813 	for (i = 0; i < options.randoms; i++) {
2814 		in_size = get_rand_data_length();
2815 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2816 		in_buf += offset;
2817 
2818 		create_rand_repeat_data(in_buf, in_size);
2819 
2820 		ret |= test_compress_stateless(in_buf, in_size, NO_FLUSH);
2821 
2822 		in_buf -= offset;
2823 
2824 		if (i % (options.randoms / 16) == 0)
2825 			printf(".");
2826 
2827 		if (ret)
2828 			return ret;
2829 	}
2830 
2831 	for (i = 0; i < options.randoms / 16; i++) {
2832 		create_rand_repeat_data(in_buf, PAGE_SIZE);
2833 		ret |= test_compress_stateless(in_buf, PAGE_SIZE, NO_FLUSH);	// good for efence
2834 		if (ret)
2835 			return ret;
2836 	}
2837 
2838 	fin_ret |= ret;
2839 
2840 	ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), SYNC_FLUSH);
2841 	if (ret)
2842 		return ret;
2843 
2844 	ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), SYNC_FLUSH);
2845 	if (ret)
2846 		return ret;
2847 
2848 	for (i = 0; i < 16; i++) {
2849 		in_size = get_rand_data_length();
2850 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2851 		in_buf += offset;
2852 
2853 		create_rand_repeat_data(in_buf, in_size);
2854 
2855 		ret |= test_compress_stateless(in_buf, in_size, SYNC_FLUSH);
2856 
2857 		in_buf -= offset;
2858 
2859 		if (ret)
2860 			return ret;
2861 	}
2862 
2863 	fin_ret |= ret;
2864 
2865 	printf("%s\n", ret ? "Fail" : "Pass");
2866 
2867 	printf("igzip_rand_test stateless FULL_FLUSH:   ");
2868 
2869 	ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), FULL_FLUSH);
2870 	if (ret)
2871 		return ret;
2872 
2873 	ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), FULL_FLUSH);
2874 	if (ret)
2875 		return ret;
2876 
2877 	for (i = 0; i < options.randoms; i++) {
2878 		in_size = get_rand_data_length();
2879 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2880 		in_buf += offset;
2881 
2882 		create_rand_repeat_data(in_buf, in_size);
2883 
2884 		ret |= test_compress_stateless(in_buf, in_size, FULL_FLUSH);
2885 
2886 		in_buf -= offset;
2887 
2888 		if (i % (options.randoms / 16) == 0)
2889 			printf(".");
2890 
2891 		if (ret)
2892 			return ret;
2893 	}
2894 
2895 	for (i = 0; i < options.randoms / 16; i++) {
2896 		create_rand_repeat_data(in_buf, PAGE_SIZE);
2897 		ret |= test_compress_stateless(in_buf, PAGE_SIZE, FULL_FLUSH);	// good for efence
2898 		if (ret)
2899 			return ret;
2900 	}
2901 	fin_ret |= ret;
2902 
2903 	printf("%s\n", ret ? "Fail" : "Pass");
2904 
2905 	printf("igzip_rand_test stateful  NO_FLUSH:     ");
2906 
2907 	memcpy(in_buf, str1, sizeof(str1));
2908 	ret = test_compress(in_buf, sizeof(str1), NO_FLUSH);
2909 	if (ret)
2910 		return ret;
2911 
2912 	memcpy(in_buf, str2, sizeof(str2));
2913 	ret |= test_compress(in_buf, sizeof(str2), NO_FLUSH);
2914 	if (ret)
2915 		return ret;
2916 
2917 	for (i = 0; i < options.randoms; i++) {
2918 		in_size = get_rand_data_length();
2919 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2920 		in_buf += offset;
2921 
2922 		create_rand_repeat_data(in_buf, in_size);
2923 
2924 		ret |= test_compress(in_buf, in_size, NO_FLUSH);
2925 
2926 		in_buf -= offset;
2927 
2928 		if (i % (options.randoms / 16) == 0)
2929 			printf(".");
2930 		if (ret)
2931 			return ret;
2932 	}
2933 
2934 	fin_ret |= ret;
2935 
2936 	printf("%s\n", ret ? "Fail" : "Pass");
2937 
2938 	printf("igzip_rand_test stateful  SYNC_FLUSH:   ");
2939 
2940 	memcpy(in_buf, str1, sizeof(str1));
2941 	ret = test_compress(in_buf, sizeof(str1), SYNC_FLUSH);
2942 	if (ret)
2943 		return ret;
2944 
2945 	memcpy(in_buf, str2, sizeof(str2));
2946 	ret |= test_compress(in_buf, sizeof(str2), SYNC_FLUSH);
2947 	if (ret)
2948 		return ret;
2949 
2950 	for (i = 0; i < options.randoms; i++) {
2951 		in_size = get_rand_data_length();
2952 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2953 		in_buf += offset;
2954 
2955 		create_rand_repeat_data(in_buf, in_size);
2956 
2957 		ret |= test_compress(in_buf, in_size, SYNC_FLUSH);
2958 
2959 		in_buf -= offset;
2960 
2961 		if (i % (options.randoms / 16) == 0)
2962 			printf(".");
2963 		if (ret)
2964 			return ret;
2965 	}
2966 
2967 	fin_ret |= ret;
2968 
2969 	printf("%s\n", ret ? "Fail" : "Pass");
2970 
2971 	printf("igzip_rand_test stateful  FULL_FLUSH:   ");
2972 
2973 	memcpy(in_buf, str1, sizeof(str1));
2974 	ret = test_compress(in_buf, sizeof(str1), FULL_FLUSH);
2975 	if (ret)
2976 		return ret;
2977 
2978 	memcpy(in_buf, str2, sizeof(str2));
2979 	ret |= test_compress(in_buf, sizeof(str2), FULL_FLUSH);
2980 	if (ret)
2981 		return ret;
2982 
2983 	for (i = 0; i < options.randoms; i++) {
2984 		in_size = get_rand_data_length();
2985 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2986 		in_buf += offset;
2987 
2988 		create_rand_repeat_data(in_buf, in_size);
2989 
2990 		ret |= test_compress(in_buf, in_size, FULL_FLUSH);
2991 
2992 		in_buf -= offset;
2993 
2994 		if (i % (options.randoms / 16) == 0)
2995 			printf(".");
2996 		if (ret)
2997 			return ret;
2998 	}
2999 
3000 	for (i = 0; i < options.randoms / 8; i++) {
3001 		in_size = get_rand_data_length();
3002 		offset = rand() % (IBUF_SIZE + 1 - in_size);
3003 		in_buf += offset;
3004 
3005 		create_rand_repeat_data(in_buf, in_size);
3006 
3007 		ret |= test_full_flush(in_buf, in_size);
3008 
3009 		in_buf -= offset;
3010 
3011 		if (ret)
3012 			return ret;
3013 	}
3014 
3015 	fin_ret |= ret;
3016 
3017 	printf("%s\n", ret ? "Fail" : "Pass");
3018 
3019 	printf("igzip_rand_test stateful  Change Flush: ");
3020 
3021 	ret = test_flush((uint8_t *) str1, sizeof(str1));
3022 	if (ret)
3023 		return ret;
3024 
3025 	ret |= test_flush((uint8_t *) str2, sizeof(str2));
3026 	if (ret)
3027 		return ret;
3028 
3029 	for (i = 0; i < options.randoms / 4; i++) {
3030 		in_size = get_rand_data_length();
3031 		offset = rand() % (IBUF_SIZE + 1 - in_size);
3032 		in_buf += offset;
3033 
3034 		create_rand_repeat_data(in_buf, in_size);
3035 
3036 		ret |= test_flush(in_buf, in_size);
3037 
3038 		in_buf -= offset;
3039 
3040 		if (i % ((options.randoms / 4) / 16) == 0)
3041 			printf(".");
3042 		if (ret)
3043 			return ret;
3044 	}
3045 
3046 	fin_ret |= ret;
3047 
3048 	printf("%s\n", ret ? "Fail" : "Pass");
3049 
3050 	if (options.do_large_test) {
3051 		printf("igzip_rand_test large input             ");
3052 
3053 		iterations = options.randoms / 256 + 1;
3054 		for (i = 0; i < iterations; i++) {
3055 			in_size = rand() % (32 * 1024) + 16 * 1024;
3056 			offset = rand() % (IBUF_SIZE + 1 - in_size);
3057 			in_buf += offset;
3058 
3059 			large_buf_size = 1;
3060 			large_buf_size <<= 32;
3061 			large_buf_size += rand() % (1024 * 1024) + 1;
3062 			create_rand_repeat_data(in_buf, in_size);
3063 
3064 			ret |= test_large(in_buf, in_size, large_buf_size);
3065 
3066 			if (ret)
3067 				return ret;
3068 
3069 			in_buf -= offset;
3070 
3071 			if (iterations < 16) {
3072 				for (j = 0; j < 16 / iterations; j++)
3073 					printf(".");
3074 			} else if (i % (iterations / 16) == 0)
3075 				printf(".");
3076 
3077 		}
3078 
3079 		if (iterations < 16) {
3080 			for (j = (16 / iterations) * iterations; j < 16; j++)
3081 				printf(".");
3082 		}
3083 
3084 		printf("%s\n", ret ? "Fail" : "Pass");
3085 	}
3086 
3087 	printf("igzip_rand_test inflate   Std Vectors:  ");
3088 
3089 	for (i = 0; i < sizeof(std_vect_array) / sizeof(struct vect_result); i++) {
3090 		ret = test_inflate(&std_vect_array[i]);
3091 		if (ret)
3092 			return ret;
3093 	}
3094 	printf("................");
3095 	printf("%s\n", ret ? "Fail" : "Pass");
3096 
3097 	printf("igzip rand test finished: %s\n",
3098 	       fin_ret ? "Some tests failed" : "All tests passed");
3099 
3100 	return fin_ret != IGZIP_COMP_OK;
3101 }
3102