aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/liblzma/common/index.c30
-rw-r--r--tests/test_index.c28
2 files changed, 44 insertions, 14 deletions
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);
}