diff --git a/src/liblzma/common/index.c b/src/liblzma/common/index.c index 46d9ff6e..014abff1 100644 --- a/src/liblzma/common/index.c +++ b/src/liblzma/common/index.c @@ -327,16 +327,14 @@ lzma_index_append(lzma_index *i, lzma_allocator *allocator, /// Initialize i->current to point to the first Record. +/// Return true if there are no Records. static bool init_current(lzma_index *i) { - if (i->head == NULL) { - assert(i->count == 0); + if (i->count == 0) return true; - } - - assert(i->count > 0); + assert(i->head != NULL); i->current.group = i->head; i->current.record = 0; i->current.stream_offset = LZMA_STREAM_HEADER_SIZE; @@ -432,21 +430,31 @@ set_info(const lzma_index *i, lzma_index_record *info) extern LZMA_API(lzma_bool) lzma_index_read(lzma_index *i, lzma_index_record *info) { + bool get_next = true; + if (i->current.group == NULL) { // We are at the beginning of the Record list. Set up - // i->current point at the first Record. Return if there - // are no Records. + // i->current to point at the first Record. Return if + // there are no Records. if (init_current(i)) return true; - } else do { - // Try to go the next Record. + + // This is the first Record. We don't need to look for the + // next Record unless this one is Stream Padding. + get_next = false; + } + + // Find the next Record that isn't Stream Padding. + while (get_next || i->current.group->paddings[i->current.record]) { + get_next = false; + if (i->current.record < i->current.group->last) ++i->current.record; else if (i->current.group->next == NULL) return true; else next_group(i); - } while (i->current.group->paddings[i->current.record]); + } // We found a new Record. Set the information to *info. set_info(i, info); @@ -623,7 +631,7 @@ lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src, ++dest->tail->last; // Copy the rest. - for (size_t i = 1; i < src->head->last; ++i) { + for (size_t i = 0; i < src->head->last; ++i) { dest->tail->unpadded_sums[dest->tail->last + 1] = vli_ceil4(dest->tail->unpadded_sums[ dest->tail->last]) diff --git a/tests/test_index.c b/tests/test_index.c index 5ce2c524..b98b6c16 100644 --- a/tests/test_index.c +++ b/tests/test_index.c @@ -14,6 +14,9 @@ #define MEMLIMIT (LZMA_VLI_C(1) << 20) +#define SMALL_COUNT 3 +#define BIG_COUNT 5555 + static lzma_index * create_empty(void) @@ -46,9 +49,8 @@ create_big(void) lzma_vli uncompressed_size = 0; // Add pseudo-random sizes (but always the same size values). - const size_t count = 5555; uint32_t n = 11; - for (size_t j = 0; j < count; ++j) { + for (size_t j = 0; j < BIG_COUNT; ++j) { n = 7019 * n + 7607; const uint32_t t = n * 3011; expect(lzma_index_append(i, NULL, t, n) == LZMA_OK); @@ -56,7 +58,7 @@ create_big(void) uncompressed_size += n; } - expect(lzma_index_count(i) == count); + expect(lzma_index_count(i) == BIG_COUNT); expect(lzma_index_total_size(i) == total_size); expect(lzma_index_uncompressed_size(i) == uncompressed_size); expect(lzma_index_total_size(i) + lzma_index_size(i) @@ -166,6 +168,7 @@ test_code(lzma_index *i) // Decode lzma_index *d; expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK); + expect(d == NULL); succeed(decoder_loop(&strm, buf, index_size)); expect(lzma_index_equal(i, d)); @@ -231,6 +234,7 @@ static void test_cat(void) { lzma_index *a, *b, *c; + lzma_index_record r; // Empty Indexes a = create_empty(); @@ -240,6 +244,7 @@ test_cat(void) expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8); expect(lzma_index_file_size(a) == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8)); + expect(lzma_index_read(a, &r)); b = create_empty(); expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK); @@ -262,6 +267,9 @@ test_cat(void) expect(lzma_index_file_size(a) == 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8); + expect(lzma_index_read(a, &r)); + lzma_index_rewind(a); + expect(lzma_index_read(a, &r)); lzma_index_end(a, NULL); // Small Indexes @@ -279,8 +287,19 @@ test_cat(void) expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK); expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12); + expect(lzma_index_count(a) == SMALL_COUNT * 4); + for (int i = SMALL_COUNT * 4; i >= 0; --i) + expect(!lzma_index_read(a, &r) ^ (i == 0)); + lzma_index_end(a, NULL); + // Mix of empty and small + a = create_empty(); + b = create_small(); + expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK); + for (int i = SMALL_COUNT; i >= 0; --i) + expect(!lzma_index_read(a, &r) ^ (i == 0)); + // Big Indexes a = create_big(); stream_size = lzma_index_stream_size(a); @@ -296,6 +315,9 @@ test_cat(void) expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK); expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12); + for (int i = BIG_COUNT * 4; i >= 0; --i) + expect(!lzma_index_read(a, &r) ^ (i == 0)); + lzma_index_end(a, NULL); }