summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2009-11-25 13:04:10 +0200
committerLasse Collin <lasse.collin@tukaani.org>2009-11-25 13:04:10 +0200
commitbd13b04e202b6f495a68eb0766f97085b7c50a06 (patch)
treefde1e56fec56109775e8722de280a37c09720788
parent1f196909143b888e062bd9a0c4ba8c34d3019bfa (diff)
downloadxz-bd13b04e202b6f495a68eb0766f97085b7c50a06.tar.gz
Fix bugs in lzma_index_read() and lzma_index_cat().
lzma_index_read() didn't skip over Stream Padding if it was the first record in the Index. lzma_index_cat() didn't combine small Indexes correctly. The test suite was updated to check for these bugs. These bugs didn't affect the xz command line tool or most users of liblzma in any way.
-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 46d9ff6..014abff 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 5ce2c52..b98b6c1 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);
}