mirror of https://git.tukaani.org/xz.git
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.
This commit is contained in:
parent
1f19690914
commit
bd13b04e20
|
@ -327,16 +327,14 @@ lzma_index_append(lzma_index *i, lzma_allocator *allocator,
|
||||||
|
|
||||||
|
|
||||||
/// Initialize i->current to point to the first Record.
|
/// Initialize i->current to point to the first Record.
|
||||||
|
/// Return true if there are no Records.
|
||||||
static bool
|
static bool
|
||||||
init_current(lzma_index *i)
|
init_current(lzma_index *i)
|
||||||
{
|
{
|
||||||
if (i->head == NULL) {
|
if (i->count == 0)
|
||||||
assert(i->count == 0);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
assert(i->count > 0);
|
|
||||||
|
|
||||||
|
assert(i->head != NULL);
|
||||||
i->current.group = i->head;
|
i->current.group = i->head;
|
||||||
i->current.record = 0;
|
i->current.record = 0;
|
||||||
i->current.stream_offset = LZMA_STREAM_HEADER_SIZE;
|
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)
|
extern LZMA_API(lzma_bool)
|
||||||
lzma_index_read(lzma_index *i, lzma_index_record *info)
|
lzma_index_read(lzma_index *i, lzma_index_record *info)
|
||||||
{
|
{
|
||||||
|
bool get_next = true;
|
||||||
|
|
||||||
if (i->current.group == NULL) {
|
if (i->current.group == NULL) {
|
||||||
// We are at the beginning of the Record list. Set up
|
// We are at the beginning of the Record list. Set up
|
||||||
// i->current point at the first Record. Return if there
|
// i->current to point at the first Record. Return if
|
||||||
// are no Records.
|
// there are no Records.
|
||||||
if (init_current(i))
|
if (init_current(i))
|
||||||
return true;
|
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)
|
if (i->current.record < i->current.group->last)
|
||||||
++i->current.record;
|
++i->current.record;
|
||||||
else if (i->current.group->next == NULL)
|
else if (i->current.group->next == NULL)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
next_group(i);
|
next_group(i);
|
||||||
} while (i->current.group->paddings[i->current.record]);
|
}
|
||||||
|
|
||||||
// We found a new Record. Set the information to *info.
|
// We found a new Record. Set the information to *info.
|
||||||
set_info(i, info);
|
set_info(i, info);
|
||||||
|
@ -623,7 +631,7 @@ lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src,
|
||||||
++dest->tail->last;
|
++dest->tail->last;
|
||||||
|
|
||||||
// Copy the rest.
|
// 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]
|
dest->tail->unpadded_sums[dest->tail->last + 1]
|
||||||
= vli_ceil4(dest->tail->unpadded_sums[
|
= vli_ceil4(dest->tail->unpadded_sums[
|
||||||
dest->tail->last])
|
dest->tail->last])
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
|
|
||||||
#define MEMLIMIT (LZMA_VLI_C(1) << 20)
|
#define MEMLIMIT (LZMA_VLI_C(1) << 20)
|
||||||
|
|
||||||
|
#define SMALL_COUNT 3
|
||||||
|
#define BIG_COUNT 5555
|
||||||
|
|
||||||
|
|
||||||
static lzma_index *
|
static lzma_index *
|
||||||
create_empty(void)
|
create_empty(void)
|
||||||
|
@ -46,9 +49,8 @@ create_big(void)
|
||||||
lzma_vli uncompressed_size = 0;
|
lzma_vli uncompressed_size = 0;
|
||||||
|
|
||||||
// Add pseudo-random sizes (but always the same size values).
|
// Add pseudo-random sizes (but always the same size values).
|
||||||
const size_t count = 5555;
|
|
||||||
uint32_t n = 11;
|
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;
|
n = 7019 * n + 7607;
|
||||||
const uint32_t t = n * 3011;
|
const uint32_t t = n * 3011;
|
||||||
expect(lzma_index_append(i, NULL, t, n) == LZMA_OK);
|
expect(lzma_index_append(i, NULL, t, n) == LZMA_OK);
|
||||||
|
@ -56,7 +58,7 @@ create_big(void)
|
||||||
uncompressed_size += n;
|
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_total_size(i) == total_size);
|
||||||
expect(lzma_index_uncompressed_size(i) == uncompressed_size);
|
expect(lzma_index_uncompressed_size(i) == uncompressed_size);
|
||||||
expect(lzma_index_total_size(i) + lzma_index_size(i)
|
expect(lzma_index_total_size(i) + lzma_index_size(i)
|
||||||
|
@ -166,6 +168,7 @@ test_code(lzma_index *i)
|
||||||
// Decode
|
// Decode
|
||||||
lzma_index *d;
|
lzma_index *d;
|
||||||
expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK);
|
expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK);
|
||||||
|
expect(d == NULL);
|
||||||
succeed(decoder_loop(&strm, buf, index_size));
|
succeed(decoder_loop(&strm, buf, index_size));
|
||||||
|
|
||||||
expect(lzma_index_equal(i, d));
|
expect(lzma_index_equal(i, d));
|
||||||
|
@ -231,6 +234,7 @@ static void
|
||||||
test_cat(void)
|
test_cat(void)
|
||||||
{
|
{
|
||||||
lzma_index *a, *b, *c;
|
lzma_index *a, *b, *c;
|
||||||
|
lzma_index_record r;
|
||||||
|
|
||||||
// Empty Indexes
|
// Empty Indexes
|
||||||
a = create_empty();
|
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_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
|
||||||
expect(lzma_index_file_size(a)
|
expect(lzma_index_file_size(a)
|
||||||
== 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
|
== 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
|
||||||
|
expect(lzma_index_read(a, &r));
|
||||||
|
|
||||||
b = create_empty();
|
b = create_empty();
|
||||||
expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
|
expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
|
||||||
|
@ -262,6 +267,9 @@ test_cat(void)
|
||||||
expect(lzma_index_file_size(a)
|
expect(lzma_index_file_size(a)
|
||||||
== 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8);
|
== 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);
|
lzma_index_end(a, NULL);
|
||||||
|
|
||||||
// Small Indexes
|
// Small Indexes
|
||||||
|
@ -279,8 +287,19 @@ test_cat(void)
|
||||||
expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK);
|
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_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);
|
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
|
// Big Indexes
|
||||||
a = create_big();
|
a = create_big();
|
||||||
stream_size = lzma_index_stream_size(a);
|
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_cat(a, b, NULL, 12) == LZMA_OK);
|
||||||
expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
|
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);
|
lzma_index_end(a, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue