From 871ad43fad0b61034a29147a4c0a42c5700d7d9e Mon Sep 17 00:00:00 2001 From: Roy Oursler Date: Tue, 21 Mar 2017 13:43:00 -0700 Subject: [PATCH] igzip: Fix bug in isal_deflate where processed is not calculated correctly. Change-Id: I61e15a18ebe3130e73010337d2d41f59e2227f08 Signed-off-by: Roy Oursler --- igzip/igzip.c | 15 ++++++++------- include/igzip_lib.h | 9 ++++++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/igzip/igzip.c b/igzip/igzip.c index 18be913..70460f4 100644 --- a/igzip/igzip.c +++ b/igzip/igzip.c @@ -369,7 +369,8 @@ static void isal_deflate_int(struct isal_zstream *stream) state->state -= ZSTATE_TMP_OFFSET; if (stream->avail_out == 0 || state->state == ZSTATE_END - || state->state == ZSTATE_NEW_HDR) + // or do not write out empty blocks since the outbuffer was processed + || (state->state == ZSTATE_NEW_HDR && stream->avail_out == 0)) return; } assert(state->tmp_out_start == state->tmp_out_end); @@ -843,7 +844,7 @@ int isal_deflate(struct isal_zstream *stream) int size = 0; uint8_t *copy_down_src = NULL; uint64_t copy_down_size = 0; - uint32_t processed = 0; + int32_t processed = -(state->b_bytes_valid - state->b_bytes_processed); if (stream->flush >= 3) return INVALID_FLUSH; @@ -852,7 +853,7 @@ int isal_deflate(struct isal_zstream *stream) avail_in = stream->avail_in; stream->total_in -= state->b_bytes_valid - state->b_bytes_processed; - while (processed < IGZIP_HIST_SIZE + ISAL_LOOK_AHEAD) { + do { size = avail_in; if (size > sizeof(state->buffer) - state->b_bytes_valid) { size = sizeof(state->buffer) - state->b_bytes_valid; @@ -868,6 +869,7 @@ int isal_deflate(struct isal_zstream *stream) stream->next_in = &state->buffer[state->b_bytes_processed]; stream->avail_in = state->b_bytes_valid - state->b_bytes_processed; state->file_start = stream->next_in - stream->total_in; + processed += stream->avail_in; if (stream->avail_in > IGZIP_HIST_SIZE || stream->end_of_stream || stream->flush != NO_FLUSH) { @@ -891,10 +893,9 @@ int isal_deflate(struct isal_zstream *stream) stream->flush = flush_type; stream->end_of_stream = end_of_stream; - if (avail_in <= 0 || stream->avail_out <= 0) - break; - processed += size; - } + processed -= stream->avail_in; + } while (processed < IGZIP_HIST_SIZE + ISAL_LOOK_AHEAD && avail_in > 0 + && stream->avail_out > 0); if (processed >= IGZIP_HIST_SIZE + ISAL_LOOK_AHEAD) { stream->next_in = next_in - stream->avail_in; diff --git a/include/igzip_lib.h b/include/igzip_lib.h index b50e8ba..3cba3fa 100644 --- a/include/igzip_lib.h +++ b/include/igzip_lib.h @@ -527,9 +527,12 @@ void isal_deflate_stateless_init(struct isal_zstream *stream); * The equivalent of the zlib FLUSH_SYNC operation is currently supported. * Flush types can be NO_FLUSH, SYNC_FLUSH or FULL_FLUSH. Default flush type is * NO_FLUSH. A SYNC_ OR FULL_ flush will byte align the deflate block by - * appending an empty stored block. Additionally FULL_FLUSH will ensure - * look back history does not include previous blocks so new blocks are fully - * independent. Switching between flush types is supported. + * appending an empty stored block once all input has been compressed, including + * the buffered input. Checking that the out_buffer is not empty or that + * internal_state.state = ZSTATE_NEW_HDR is sufficient to guarantee all input + * has been flushed. Additionally FULL_FLUSH will ensure look back history does + * not include previous blocks so new blocks are fully independent. Switching + * between flush types is supported. * * If the gzip_flag is set to IGZIP_GZIP, a generic gzip header and the gzip * trailer are written around the deflate compressed data. If gzip_flag is set