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