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