Tests: Refactor test_block_header.c.
test_block_header now achieves higher test coverage. Also the test will now compile and skip properly if encoders or decoders are disabled. Thanks to Sebastian Andrzej Siewior.
This commit is contained in:
parent
8496331895
commit
827ac5b482
|
@ -3,7 +3,8 @@
|
||||||
/// \file test_block_header.c
|
/// \file test_block_header.c
|
||||||
/// \brief Tests Block Header coders
|
/// \brief Tests Block Header coders
|
||||||
//
|
//
|
||||||
// Author: Lasse Collin
|
// Authors: Lasse Collin
|
||||||
|
// Jia Tan
|
||||||
//
|
//
|
||||||
// This file has been put into the public domain.
|
// This file has been put into the public domain.
|
||||||
// You can do whatever you want with this file.
|
// You can do whatever you want with this file.
|
||||||
|
@ -13,12 +14,10 @@
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
|
||||||
|
|
||||||
static uint8_t buf[LZMA_BLOCK_HEADER_SIZE_MAX];
|
|
||||||
static lzma_block known_options;
|
|
||||||
static lzma_block decoded_options;
|
|
||||||
|
|
||||||
static lzma_options_lzma opt_lzma;
|
static lzma_options_lzma opt_lzma;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_ENCODERS
|
||||||
static lzma_filter filters_none[1] = {
|
static lzma_filter filters_none[1] = {
|
||||||
{
|
{
|
||||||
.id = LZMA_VLI_UNKNOWN,
|
.id = LZMA_VLI_UNKNOWN,
|
||||||
|
@ -75,163 +74,423 @@ static lzma_filter filters_five[6] = {
|
||||||
.id = LZMA_VLI_UNKNOWN,
|
.id = LZMA_VLI_UNKNOWN,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
code(void)
|
test_lzma_block_header_size(void)
|
||||||
{
|
{
|
||||||
assert_lzma_ret(lzma_block_header_encode(&known_options, buf),
|
#ifndef HAVE_ENCODERS
|
||||||
LZMA_OK);
|
assert_skip("Encoder support disabled");
|
||||||
|
#else
|
||||||
|
if (!lzma_filter_encoder_is_supported(LZMA_FILTER_X86))
|
||||||
|
assert_skip("x86 BCJ encoder is disabled");
|
||||||
|
|
||||||
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
lzma_block block = {
|
||||||
memcrap(filters, sizeof(filters));
|
.version = 0,
|
||||||
memcrap(&decoded_options, sizeof(decoded_options));
|
|
||||||
|
|
||||||
decoded_options.header_size = known_options.header_size;
|
|
||||||
decoded_options.check = known_options.check;
|
|
||||||
decoded_options.filters = filters;
|
|
||||||
assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
|
|
||||||
LZMA_OK);
|
|
||||||
|
|
||||||
assert_uint_eq(decoded_options.compressed_size,
|
|
||||||
known_options.compressed_size);
|
|
||||||
assert_uint_eq(decoded_options.uncompressed_size,
|
|
||||||
known_options.uncompressed_size);
|
|
||||||
|
|
||||||
for (size_t i = 0; known_options.filters[i].id
|
|
||||||
!= LZMA_VLI_UNKNOWN; ++i)
|
|
||||||
assert_uint_eq(filters[i].id, known_options.filters[i].id);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < LZMA_FILTERS_MAX; ++i)
|
|
||||||
free(decoded_options.filters[i].options);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
test1(void)
|
|
||||||
{
|
|
||||||
known_options = (lzma_block){
|
|
||||||
.check = LZMA_CHECK_NONE,
|
|
||||||
.compressed_size = LZMA_VLI_UNKNOWN,
|
|
||||||
.uncompressed_size = LZMA_VLI_UNKNOWN,
|
|
||||||
.filters = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options),
|
|
||||||
LZMA_PROG_ERROR);
|
|
||||||
|
|
||||||
known_options.filters = filters_none;
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options),
|
|
||||||
LZMA_PROG_ERROR);
|
|
||||||
|
|
||||||
known_options.filters = filters_five;
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options),
|
|
||||||
LZMA_PROG_ERROR);
|
|
||||||
|
|
||||||
known_options.filters = filters_one;
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
|
|
||||||
|
|
||||||
// Some invalid value, which gets ignored.
|
|
||||||
known_options.check = (lzma_check)(99);
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
|
|
||||||
|
|
||||||
known_options.compressed_size = 5;
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
|
|
||||||
|
|
||||||
known_options.compressed_size = 0; // Cannot be zero.
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options),
|
|
||||||
LZMA_PROG_ERROR);
|
|
||||||
|
|
||||||
// LZMA_VLI_MAX is too big to keep the total size of the Block
|
|
||||||
// a valid VLI, but lzma_block_header_size() is not meant
|
|
||||||
// to validate it. (lzma_block_header_encode() must validate it.)
|
|
||||||
known_options.compressed_size = LZMA_VLI_MAX;
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
|
|
||||||
|
|
||||||
known_options.compressed_size = LZMA_VLI_UNKNOWN;
|
|
||||||
known_options.uncompressed_size = 0;
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
|
|
||||||
|
|
||||||
known_options.uncompressed_size = LZMA_VLI_MAX + 1;
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options),
|
|
||||||
LZMA_PROG_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
test2(void)
|
|
||||||
{
|
|
||||||
known_options = (lzma_block){
|
|
||||||
.check = LZMA_CHECK_CRC32,
|
|
||||||
.compressed_size = LZMA_VLI_UNKNOWN,
|
|
||||||
.uncompressed_size = LZMA_VLI_UNKNOWN,
|
|
||||||
.filters = filters_four,
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
|
|
||||||
code();
|
|
||||||
|
|
||||||
known_options.compressed_size = 123456;
|
|
||||||
known_options.uncompressed_size = 234567;
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
|
|
||||||
code();
|
|
||||||
|
|
||||||
// We can make the sizes smaller while keeping the header size
|
|
||||||
// the same.
|
|
||||||
known_options.compressed_size = 12;
|
|
||||||
known_options.uncompressed_size = 23;
|
|
||||||
code();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
test3(void)
|
|
||||||
{
|
|
||||||
known_options = (lzma_block){
|
|
||||||
.check = LZMA_CHECK_CRC32,
|
|
||||||
.compressed_size = LZMA_VLI_UNKNOWN,
|
|
||||||
.uncompressed_size = LZMA_VLI_UNKNOWN,
|
|
||||||
.filters = filters_one,
|
.filters = filters_one,
|
||||||
|
.compressed_size = LZMA_VLI_UNKNOWN,
|
||||||
|
.uncompressed_size = LZMA_VLI_UNKNOWN,
|
||||||
|
.check = LZMA_CHECK_CRC32
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_lzma_ret(lzma_block_header_size(&known_options), LZMA_OK);
|
// Test that all initial options are valid
|
||||||
known_options.header_size += 4;
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
assert_lzma_ret(lzma_block_header_encode(&known_options, buf),
|
assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN);
|
||||||
LZMA_OK);
|
assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
assert_uint_eq(block.header_size % 4, 0);
|
||||||
|
|
||||||
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
// Test invalid version number
|
||||||
decoded_options.header_size = known_options.header_size;
|
for (uint32_t i = 2; i < 20; i++) {
|
||||||
decoded_options.check = known_options.check;
|
block.version = i;
|
||||||
decoded_options.filters = filters;
|
assert_lzma_ret(lzma_block_header_size(&block),
|
||||||
|
LZMA_OPTIONS_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
// Wrong size
|
block.version = 1;
|
||||||
++buf[0];
|
|
||||||
assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
|
// Test invalid compressed size
|
||||||
|
block.compressed_size = 0;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
block.compressed_size = LZMA_VLI_MAX + 1;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR);
|
||||||
|
block.compressed_size = LZMA_VLI_UNKNOWN;
|
||||||
|
|
||||||
|
// Test invalid uncompressed size
|
||||||
|
block.uncompressed_size = LZMA_VLI_MAX + 1;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR);
|
||||||
|
block.uncompressed_size = LZMA_VLI_MAX;
|
||||||
|
|
||||||
|
// Test invalid filters
|
||||||
|
block.filters = NULL;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
block.filters = filters_none;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
block.filters = filters_five;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
block.filters = filters_one;
|
||||||
|
|
||||||
|
// Test setting compressed_size to something valid
|
||||||
|
block.compressed_size = 4096;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN);
|
||||||
|
assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
assert_uint_eq(block.header_size % 4, 0);
|
||||||
|
|
||||||
|
// Test setting uncompressed_size to something valid
|
||||||
|
block.uncompressed_size = 4096;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN);
|
||||||
|
assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
assert_uint_eq(block.header_size % 4, 0);
|
||||||
|
|
||||||
|
// This should pass, but header_size will be an invalid value
|
||||||
|
// because the total block size will not be able to fit in a valid
|
||||||
|
// lzma_vli. This way a temporary value can be used to reserve
|
||||||
|
// space for the header and later the actual value can be set.
|
||||||
|
block.compressed_size = LZMA_VLI_MAX;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN);
|
||||||
|
assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
assert_uint_eq(block.header_size % 4, 0);
|
||||||
|
|
||||||
|
// Use an invalid value for a filter option. This should still pass
|
||||||
|
// because the size of the LZMA2 properties is known by liblzma
|
||||||
|
// without reading any of the options so it doesn't validate them.
|
||||||
|
lzma_options_lzma bad_ops;
|
||||||
|
assert_false(lzma_lzma_preset(&bad_ops, 1));
|
||||||
|
bad_ops.pb = 0x1000;
|
||||||
|
|
||||||
|
lzma_filter bad_filters[2] = {
|
||||||
|
{
|
||||||
|
.id = LZMA_FILTER_LZMA2,
|
||||||
|
.options = &bad_ops
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.id = LZMA_VLI_UNKNOWN,
|
||||||
|
.options = NULL
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
block.filters = bad_filters;
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN);
|
||||||
|
assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
assert_uint_eq(block.header_size % 4, 0);
|
||||||
|
|
||||||
|
// Use an invalid block option. The check type isn't stored in
|
||||||
|
// the Block Header and so _header_size ignores it.
|
||||||
|
block.check = 0x1000;
|
||||||
|
block.ignore_check = false;
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN);
|
||||||
|
assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
assert_uint_eq(block.header_size % 4, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_lzma_block_header_encode(void)
|
||||||
|
{
|
||||||
|
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
|
||||||
|
assert_skip("Encoder or decoder support disabled");
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (!lzma_filter_encoder_is_supported(LZMA_FILTER_X86)
|
||||||
|
|| !lzma_filter_decoder_is_supported(LZMA_FILTER_X86))
|
||||||
|
assert_skip("x86 BCJ encoder and/or decoder "
|
||||||
|
"is disabled");
|
||||||
|
|
||||||
|
lzma_block block = {
|
||||||
|
.version = 1,
|
||||||
|
.filters = filters_one,
|
||||||
|
.compressed_size = LZMA_VLI_UNKNOWN,
|
||||||
|
.uncompressed_size = LZMA_VLI_UNKNOWN,
|
||||||
|
.check = LZMA_CHECK_CRC32,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ensure all block options are valid before changes are tested
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
|
||||||
|
uint8_t out[LZMA_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
|
||||||
|
// Test invalid block version
|
||||||
|
for (uint32_t i = 2; i < 20; i++) {
|
||||||
|
block.version = i;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
LZMA_PROG_ERROR);
|
LZMA_PROG_ERROR);
|
||||||
--buf[0];
|
}
|
||||||
|
|
||||||
// Wrong CRC32
|
block.version = 1;
|
||||||
buf[known_options.header_size - 1] ^= 1;
|
|
||||||
assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
|
// Test invalid header size (< min, > max, % 4 != 0)
|
||||||
|
block.header_size = LZMA_BLOCK_HEADER_SIZE_MIN - 4;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
block.header_size = LZMA_BLOCK_HEADER_SIZE_MIN + 2;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
block.header_size = LZMA_BLOCK_HEADER_SIZE_MAX + 4;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
|
||||||
|
// Test invalid compressed_size
|
||||||
|
block.compressed_size = 0;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
block.compressed_size = LZMA_VLI_MAX + 1;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
// This test passes test_lzma_block_header_size, but should
|
||||||
|
// fail here because there is not enough space to encode the
|
||||||
|
// proper block size because the total size is too big to fit
|
||||||
|
// in an lzma_vli
|
||||||
|
block.compressed_size = LZMA_VLI_MAX;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
block.compressed_size = LZMA_VLI_UNKNOWN;
|
||||||
|
|
||||||
|
// Test invalid uncompressed size
|
||||||
|
block.uncompressed_size = LZMA_VLI_MAX + 1;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
block.uncompressed_size = LZMA_VLI_UNKNOWN;
|
||||||
|
|
||||||
|
// Test invalid block check
|
||||||
|
block.check = 0x1000;
|
||||||
|
block.ignore_check = false;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
block.check = LZMA_CHECK_CRC32;
|
||||||
|
|
||||||
|
// Test invalid filters
|
||||||
|
block.filters = NULL;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
block.filters = filters_none;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
block.filters = filters_five;
|
||||||
|
block.header_size = LZMA_BLOCK_HEADER_SIZE_MAX - 4;
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
// Test valid encoding and verify bytes of block header.
|
||||||
|
// More complicated tests for encoding headers are included
|
||||||
|
// in test_lzma_block_header_decode.
|
||||||
|
block.filters = filters_one;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK);
|
||||||
|
|
||||||
|
// First read block header size from out and verify
|
||||||
|
// that it == (encoded size + 1) * 4
|
||||||
|
uint32_t header_size = (out[0] + 1U) * 4;
|
||||||
|
assert_uint_eq(header_size, block.header_size);
|
||||||
|
|
||||||
|
// Next read block flags
|
||||||
|
uint8_t flags = out[1];
|
||||||
|
|
||||||
|
// Should have number of filters = 1
|
||||||
|
assert_uint_eq((flags & 0x3) + 1, 1);
|
||||||
|
|
||||||
|
// Bits 2-7 must be empty not set
|
||||||
|
assert_uint_eq(flags & (0xFF - 0x3), 0);
|
||||||
|
|
||||||
|
// Verify filter flags
|
||||||
|
// Decode Filter ID
|
||||||
|
lzma_vli filter_id = 0;
|
||||||
|
size_t pos = 2;
|
||||||
|
assert_lzma_ret(lzma_vli_decode(&filter_id, NULL, out,
|
||||||
|
&pos, header_size), LZMA_OK);
|
||||||
|
assert_uint_eq(filter_id, filters_one[0].id);
|
||||||
|
|
||||||
|
// Decode Size of Properties
|
||||||
|
lzma_vli prop_size = 0;
|
||||||
|
assert_lzma_ret(lzma_vli_decode(&prop_size, NULL, out,
|
||||||
|
&pos, header_size), LZMA_OK);
|
||||||
|
|
||||||
|
// LZMA2 has 1 byte prop size
|
||||||
|
assert_uint_eq(prop_size, 1);
|
||||||
|
uint8_t expected_filter_props = 0;
|
||||||
|
assert_lzma_ret(lzma_properties_encode(filters_one,
|
||||||
|
&expected_filter_props), LZMA_OK);
|
||||||
|
assert_uint_eq(out[pos], expected_filter_props);
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
// Check null-padding
|
||||||
|
for (size_t i = pos; i < header_size - 4; i++)
|
||||||
|
assert_uint_eq(out[i], 0);
|
||||||
|
|
||||||
|
// Check CRC32
|
||||||
|
assert_uint_eq(read32le(&out[header_size - 4]), lzma_crc32(out,
|
||||||
|
header_size - 4, 0));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
|
||||||
|
// Helper function to compare two lzma_block structures field by field
|
||||||
|
static void
|
||||||
|
compare_blocks(lzma_block *block_expected, lzma_block *block_actual)
|
||||||
|
{
|
||||||
|
assert_uint_eq(block_actual->version, block_expected->version);
|
||||||
|
assert_uint_eq(block_actual->compressed_size,
|
||||||
|
block_expected->compressed_size);
|
||||||
|
assert_uint_eq(block_actual->uncompressed_size,
|
||||||
|
block_expected->uncompressed_size);
|
||||||
|
assert_uint_eq(block_actual->check, block_expected->check);
|
||||||
|
assert_uint_eq(block_actual->header_size, block_expected->header_size);
|
||||||
|
|
||||||
|
// Compare filter IDs
|
||||||
|
assert_true(block_expected->filters && block_actual->filters);
|
||||||
|
lzma_filter expected_filter = block_expected->filters[0];
|
||||||
|
uint32_t filter_count = 0;
|
||||||
|
while (expected_filter.id != LZMA_VLI_UNKNOWN) {
|
||||||
|
assert_uint_eq(block_actual->filters[filter_count].id,
|
||||||
|
expected_filter.id);
|
||||||
|
expected_filter = block_expected->filters[++filter_count];
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_uint_eq(block_actual->filters[filter_count].id,
|
||||||
|
LZMA_VLI_UNKNOWN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_lzma_block_header_decode(void)
|
||||||
|
{
|
||||||
|
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
|
||||||
|
assert_skip("Encoder or decoder support disabled");
|
||||||
|
#else
|
||||||
|
if (!lzma_filter_encoder_is_supported(LZMA_FILTER_X86)
|
||||||
|
|| !lzma_filter_decoder_is_supported(LZMA_FILTER_X86))
|
||||||
|
assert_skip("x86 BCJ encoder and/or decoder "
|
||||||
|
"is disabled");
|
||||||
|
|
||||||
|
lzma_block block = {
|
||||||
|
.filters = filters_one,
|
||||||
|
.compressed_size = LZMA_VLI_UNKNOWN,
|
||||||
|
.uncompressed_size = LZMA_VLI_UNKNOWN,
|
||||||
|
.check = LZMA_CHECK_CRC32,
|
||||||
|
.version = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
|
||||||
|
// Encode block header with simple options
|
||||||
|
uint8_t out[LZMA_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK);
|
||||||
|
|
||||||
|
// Decode block header and check that the options match
|
||||||
|
lzma_filter decoded_filters[LZMA_FILTERS_MAX + 1];
|
||||||
|
lzma_block decoded_block = {
|
||||||
|
.version = 0,
|
||||||
|
.filters = decoded_filters,
|
||||||
|
.check = LZMA_CHECK_CRC32
|
||||||
|
};
|
||||||
|
decoded_block.header_size = lzma_block_header_size_decode(out[0]);
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
|
LZMA_OK);
|
||||||
|
compare_blocks(&block, &decoded_block);
|
||||||
|
|
||||||
|
// Reset output buffer and decoded_block
|
||||||
|
memzero(out, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
memzero(&decoded_block, sizeof(lzma_block));
|
||||||
|
decoded_block.filters = decoded_filters;
|
||||||
|
decoded_block.check = LZMA_CHECK_CRC32;
|
||||||
|
|
||||||
|
// Test with compressed size set
|
||||||
|
block.compressed_size = 4096;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK);
|
||||||
|
decoded_block.header_size = lzma_block_header_size_decode(out[0]);
|
||||||
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
|
LZMA_OK);
|
||||||
|
compare_blocks(&block, &decoded_block);
|
||||||
|
|
||||||
|
memzero(out, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
memzero(&decoded_block, sizeof(lzma_block));
|
||||||
|
decoded_block.filters = decoded_filters;
|
||||||
|
decoded_block.check = LZMA_CHECK_CRC32;
|
||||||
|
|
||||||
|
// Test with uncompressed size set
|
||||||
|
block.uncompressed_size = 4096;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK);
|
||||||
|
decoded_block.header_size = lzma_block_header_size_decode(out[0]);
|
||||||
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
|
LZMA_OK);
|
||||||
|
compare_blocks(&block, &decoded_block);
|
||||||
|
|
||||||
|
memzero(out, LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
memzero(&decoded_block, sizeof(lzma_block));
|
||||||
|
decoded_block.filters = decoded_filters;
|
||||||
|
decoded_block.check = LZMA_CHECK_CRC32;
|
||||||
|
|
||||||
|
// Test with multiple filters
|
||||||
|
block.filters = filters_four;
|
||||||
|
assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK);
|
||||||
|
assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK);
|
||||||
|
decoded_block.header_size = lzma_block_header_size_decode(out[0]);
|
||||||
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
|
LZMA_OK);
|
||||||
|
compare_blocks(&block, &decoded_block);
|
||||||
|
|
||||||
|
memzero(&decoded_block, sizeof(lzma_block));
|
||||||
|
decoded_block.filters = decoded_filters;
|
||||||
|
decoded_block.check = LZMA_CHECK_CRC32;
|
||||||
|
decoded_block.header_size = lzma_block_header_size_decode(out[0]);
|
||||||
|
|
||||||
|
// Test with too high version. The decoder will set it to a version
|
||||||
|
// that it supports.
|
||||||
|
decoded_block.version = 2;
|
||||||
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
|
LZMA_OK);
|
||||||
|
assert_uint_eq(decoded_block.version, 1);
|
||||||
|
|
||||||
|
// Test bad check type
|
||||||
|
decoded_block.check = LZMA_CHECK_ID_MAX + 1;
|
||||||
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
decoded_block.check = LZMA_CHECK_CRC32;
|
||||||
|
|
||||||
|
// Test bad check value
|
||||||
|
out[decoded_block.header_size - 1] -= 10;
|
||||||
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
LZMA_DATA_ERROR);
|
LZMA_DATA_ERROR);
|
||||||
buf[known_options.header_size - 1] ^= 1;
|
out[decoded_block.header_size - 1] += 10;
|
||||||
|
|
||||||
// Unsupported filter
|
// Test non-NULL padding
|
||||||
// NOTE: This may need updating when new IDs become supported.
|
out[decoded_block.header_size - 5] = 1;
|
||||||
buf[2] ^= 0x1F;
|
|
||||||
write32le(buf + known_options.header_size - 4,
|
|
||||||
lzma_crc32(buf, known_options.header_size - 4, 0));
|
|
||||||
assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
|
|
||||||
LZMA_OPTIONS_ERROR);
|
|
||||||
buf[2] ^= 0x1F;
|
|
||||||
|
|
||||||
// Non-nul Padding
|
// Recompute CRC32
|
||||||
buf[known_options.header_size - 4 - 1] ^= 1;
|
write32le(&out[decoded_block.header_size - 4], lzma_crc32(out,
|
||||||
write32le(buf + known_options.header_size - 4,
|
decoded_block.header_size - 4, 0));
|
||||||
lzma_crc32(buf, known_options.header_size - 4, 0));
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
assert_lzma_ret(lzma_block_header_decode(&decoded_options, NULL, buf),
|
|
||||||
LZMA_OPTIONS_ERROR);
|
LZMA_OPTIONS_ERROR);
|
||||||
buf[known_options.header_size - 4 - 1] ^= 1;
|
|
||||||
|
// Test unsupported flags
|
||||||
|
out[1] = 0xFF;
|
||||||
|
|
||||||
|
// Recompute CRC32
|
||||||
|
write32le(&out[decoded_block.header_size - 4], lzma_crc32(out,
|
||||||
|
decoded_block.header_size - 4, 0));
|
||||||
|
assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out),
|
||||||
|
LZMA_OPTIONS_ERROR);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,17 +499,12 @@ main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
tuktest_start(argc, argv);
|
tuktest_start(argc, argv);
|
||||||
|
|
||||||
if (!lzma_filter_encoder_is_supported(LZMA_FILTER_X86)
|
|
||||||
|| !lzma_filter_decoder_is_supported(LZMA_FILTER_X86))
|
|
||||||
tuktest_early_skip("x86 BCJ encoder and/or decoder "
|
|
||||||
"is disabled");
|
|
||||||
|
|
||||||
if (lzma_lzma_preset(&opt_lzma, 1))
|
if (lzma_lzma_preset(&opt_lzma, 1))
|
||||||
tuktest_error("lzma_lzma_preset() failed");
|
tuktest_error("lzma_lzma_preset() failed");
|
||||||
|
|
||||||
tuktest_run(test1);
|
tuktest_run(test_lzma_block_header_size);
|
||||||
tuktest_run(test2);
|
tuktest_run(test_lzma_block_header_encode);
|
||||||
tuktest_run(test3);
|
tuktest_run(test_lzma_block_header_decode);
|
||||||
|
|
||||||
return tuktest_end();
|
return tuktest_end();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue