diff --git a/programs/igzip_cli.c b/programs/igzip_cli.c index 9a20b9b..53124af 100644 --- a/programs/igzip_cli.c +++ b/programs/igzip_cli.c @@ -817,6 +817,7 @@ int decompress_file(void) int suffix_index = 0; uint32_t file_time; + // Allocate mem and setup to hold gzip header info if (infile_name_len == stdin_file_name_len && infile_name != NULL && memcmp(infile_name, stdin_file_name, infile_name_len) == 0) { @@ -884,6 +885,7 @@ int decompress_file(void) state.next_in = inbuf; state.avail_in = fread_safe(state.next_in, 1, inbuf_size, in, infile_name); + // Actually read and save the header info ret = isal_read_gzip_header(&state, &gz_hdr); if (ret != ISAL_DECOMP_OK) { log_print(ERROR, "igzip: Error invalid gzip header found for file %s\n", @@ -915,6 +917,7 @@ int decompress_file(void) goto decompress_file_cleanup; } + // Start reading in compressed data and decompress do { if (state.avail_in == 0) { state.next_in = inbuf; @@ -936,7 +939,55 @@ int decompress_file(void) if (out != NULL) fwrite_safe(outbuf, 1, state.next_out - outbuf, out, outfile_name); - } while (!feof(in) || state.avail_out == 0); + } while (state.block_state != ISAL_BLOCK_FINISH // while not done + && (!feof(in) || state.avail_out == 0) // and work to do + ); + + // Add the following to look for and decode additional concatenated files + if (!feof(in) && state.avail_in == 0) { + state.next_in = inbuf; + state.avail_in = fread_safe(state.next_in, 1, inbuf_size, in, infile_name); + } + + while (state.avail_in > 0 && state.next_in[0] == 31) { + // Look for magic numbers for gzip header. Follows the gzread() decision + // whether to treat as trailing junk + if (state.avail_in > 1 && state.next_in[1] != 139) + break; + + isal_inflate_reset(&state); + state.crc_flag = ISAL_GZIP; // Let isal_inflate() process extra headers + do { + if (state.avail_in == 0 && !feof(in)) { + state.next_in = inbuf; + state.avail_in = + fread_safe(state.next_in, 1, inbuf_size, in, infile_name); + } + + state.next_out = outbuf; + state.avail_out = outbuf_size; + + ret = isal_inflate(&state); + if (ret != ISAL_DECOMP_OK) { + log_print(ERROR, + "igzip: Error while decompressing extra concatenated" + "gzip files on %s\n", infile_name); + goto decompress_file_cleanup; + } + + if (out != NULL) + fwrite_safe(outbuf, 1, state.next_out - outbuf, out, + outfile_name); + + } while (state.block_state != ISAL_BLOCK_FINISH + && (!feof(in) || state.avail_out == 0)); + + if (!feof(in) && state.avail_in == 0) { + state.next_in = inbuf; + state.avail_in = + fread_safe(state.next_in, 1, inbuf_size, in, infile_name); + } + } if (state.block_state != ISAL_BLOCK_FINISH) log_print(ERROR, "igzip: Error %s does not contain a complete gzip file\n", diff --git a/programs/igzip_cli_check.sh b/programs/igzip_cli_check.sh index da83578..5d97763 100755 --- a/programs/igzip_cli_check.sh +++ b/programs/igzip_cli_check.sh @@ -77,6 +77,22 @@ cat $TEST_FILE | $IGZIP | $IGZIP -d | $DIFF $TEST_FILE - || ret=1 cat $TEST_FILE | $IGZIP - | $IGZIP -d - | $DIFF $TEST_FILE - || ret=1 pass_check $ret "Piping compression and decompression" +# Test multiple concatenated gzip files +ret=0 +(for i in `seq 3`; do $IGZIP -c $TEST_FILE ; done) | $IGZIP -t || ret=1 +pass_check $ret "Multiple gzip concatenated files" + +if command -V md5sum >/dev/null 2>&1; then + sum1=$((for i in `seq 15`; do $IGZIP -c $TEST_FILE; done) | $IGZIP -cd | md5sum) + sum2=$((for i in `seq 15`; do cat $TEST_FILE; done) | md5sum) + [[ "$sum1" == "$sum2" ]] && ret=0 || ret=1 + pass_check $ret "Multiple large gzip concat test" + clear_dir +else + echo "Skip: Multiple large gzip concat test" +fi + + #Test outifle options $IGZIP $TEST_FILE -o $file2$ds && $IGZIP $file2$ds -d -o $file1 && \ test -f $file2$ds && test -f $file1 && $DIFF $TEST_FILE $file1