mirror of https://git.tukaani.org/xz.git
Tests: Refactors existing filter flags tests.
Converts the existing filter flags tests into tuktests.
This commit is contained in:
parent
36edc65ab4
commit
5c9fdd3bf5
|
@ -3,7 +3,8 @@
|
||||||
/// \file test_filter_flags.c
|
/// \file test_filter_flags.c
|
||||||
/// \brief Tests Filter Flags coders
|
/// \brief Tests Filter Flags coders
|
||||||
//
|
//
|
||||||
// Author: Lasse Collin
|
// Authors: Jia Tan
|
||||||
|
// Lasse Collin
|
||||||
//
|
//
|
||||||
// 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.
|
||||||
|
@ -11,248 +12,506 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
// Including the internal header file for access to the
|
||||||
|
// LZMA_FILTER_RESERVED_START macro
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
|
||||||
static uint8_t buffer[4096];
|
// Used to create filters and easily to set id and options
|
||||||
static lzma_filter known_flags;
|
#define INIT_FILTER(_id, _options) {\
|
||||||
static lzma_filter decoded_flags;
|
.id = _id, \
|
||||||
static lzma_stream strm = LZMA_STREAM_INIT;
|
.options = _options \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
#if defined(HAVE_ENCODERS)
|
||||||
encode(uint32_t known_size)
|
// No tests are run without encoders, so init the global filters
|
||||||
|
// only when the encoders are enabled.
|
||||||
|
static lzma_filter lzma1_filter = INIT_FILTER(LZMA_FILTER_LZMA1, NULL);
|
||||||
|
static lzma_filter lzma2_filter = INIT_FILTER(LZMA_FILTER_LZMA2, NULL);
|
||||||
|
static lzma_filter delta_filter = INIT_FILTER(LZMA_FILTER_DELTA, NULL);
|
||||||
|
|
||||||
|
static lzma_filter bcj_filters_encoders[] = {
|
||||||
|
#ifdef HAVE_ENCODER_X86
|
||||||
|
INIT_FILTER(LZMA_FILTER_X86, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ENCODER_POWERPC
|
||||||
|
INIT_FILTER(LZMA_FILTER_POWERPC, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ENCODER_IA64
|
||||||
|
INIT_FILTER(LZMA_FILTER_IA64, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ENCODER_ARM
|
||||||
|
INIT_FILTER(LZMA_FILTER_ARM, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ENCODER_ARM64
|
||||||
|
INIT_FILTER(LZMA_FILTER_ARM64, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ENCODER_ARMTHUMB
|
||||||
|
INIT_FILTER(LZMA_FILTER_ARMTHUMB, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ENCODER_SPARC
|
||||||
|
INIT_FILTER(LZMA_FILTER_SPARC, NULL),
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// HAVE_ENCODERS ifdef not termianted here because decoders are
|
||||||
|
// only used if encoders are, but encoders can still be used
|
||||||
|
// even if decoders are not.
|
||||||
|
|
||||||
|
#ifdef HAVE_DECODERS
|
||||||
|
static lzma_filter bcj_filters_decoders[] = {
|
||||||
|
#ifdef HAVE_DECODER_X86
|
||||||
|
INIT_FILTER(LZMA_FILTER_X86, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DECODER_POWERPC
|
||||||
|
INIT_FILTER(LZMA_FILTER_POWERPC, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DECODER_IA64
|
||||||
|
INIT_FILTER(LZMA_FILTER_IA64, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DECODER_ARM
|
||||||
|
INIT_FILTER(LZMA_FILTER_ARM, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DECODER_ARM64
|
||||||
|
INIT_FILTER(LZMA_FILTER_ARM64, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DECODER_ARMTHUMB
|
||||||
|
INIT_FILTER(LZMA_FILTER_ARMTHUMB, NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DECODER_SPARC
|
||||||
|
INIT_FILTER(LZMA_FILTER_SPARC, NULL),
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_lzma_filter_flags_size(void)
|
||||||
{
|
{
|
||||||
memcrap(buffer, sizeof(buffer));
|
#ifndef HAVE_ENCODERS
|
||||||
|
assert_skip("Encoder support disabled");
|
||||||
|
#else
|
||||||
|
// For each supported filter, test that the size can be calculated
|
||||||
|
// and that the size calculated is reasonable. A reasonable size
|
||||||
|
// must be greater than 0, but less than the maximum size for the
|
||||||
|
// block header.
|
||||||
|
uint32_t size = 0;
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA1)) {
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&size,
|
||||||
|
&lzma1_filter), LZMA_PROG_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t tmp;
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||||
if (lzma_filter_flags_size(&tmp, &known_flags) != LZMA_OK)
|
assert_lzma_ret(lzma_filter_flags_size(&size,
|
||||||
return true;
|
&lzma2_filter), LZMA_OK);
|
||||||
|
assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp != known_size)
|
for (uint32_t i = 0; i < ARRAY_SIZE(bcj_filters_encoders); i++) {
|
||||||
return true;
|
assert_lzma_ret(lzma_filter_flags_size(&size,
|
||||||
|
&bcj_filters_encoders[i]), LZMA_OK);
|
||||||
|
assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&size,
|
||||||
|
&delta_filter), LZMA_OK);
|
||||||
|
assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test invalid filter ids
|
||||||
|
lzma_filter bad_filter = INIT_FILTER(2, NULL);
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter),
|
||||||
|
LZMA_OPTIONS_ERROR);
|
||||||
|
bad_filter.id = LZMA_VLI_MAX;
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
bad_filter.id = LZMA_FILTER_RESERVED_START;
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function for test_lzma_filter_flags_encode.
|
||||||
|
// The should_encode parameter represents if the encoding operation
|
||||||
|
// is expected to fail.
|
||||||
|
// Avoid data -> encode -> decode -> compare to data.
|
||||||
|
// Instead create expected encoding and compare to result from
|
||||||
|
// lzma_filter_flags_encode.
|
||||||
|
// Filter flags for xz are encoded as:
|
||||||
|
// |Filter ID (VLI)|Size of Properties (VLI)|Filter Properties|
|
||||||
|
#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
|
||||||
|
static void
|
||||||
|
verify_filter_flags_encode(lzma_filter *filter, bool should_encode)
|
||||||
|
{
|
||||||
|
uint32_t size = 0;
|
||||||
|
// First calculate the size of filter flags to know how much
|
||||||
|
// memory to allocate to hold the filter flags encoded
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&size, filter), LZMA_OK);
|
||||||
|
uint8_t *encoded_out = tuktest_malloc(size * sizeof(uint8_t));
|
||||||
size_t out_pos = 0;
|
size_t out_pos = 0;
|
||||||
if (lzma_filter_flags_encode(&known_flags,
|
if(!should_encode) {
|
||||||
buffer, &out_pos, known_size) != LZMA_OK)
|
assert_false(lzma_filter_flags_encode(filter, encoded_out,
|
||||||
return true;
|
&out_pos, size) == LZMA_OK);
|
||||||
|
return;
|
||||||
if (out_pos != known_size)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool
|
|
||||||
decode_ret(uint32_t known_size, lzma_ret expected_ret)
|
|
||||||
{
|
|
||||||
memcrap(&decoded_flags, sizeof(decoded_flags));
|
|
||||||
|
|
||||||
size_t pos = 0;
|
|
||||||
if (lzma_filter_flags_decode(&decoded_flags, NULL,
|
|
||||||
buffer, &pos, known_size) != expected_ret
|
|
||||||
|| pos != known_size)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool
|
|
||||||
decode(uint32_t known_size)
|
|
||||||
{
|
|
||||||
if (decode_ret(known_size, LZMA_OK))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (known_flags.id != decoded_flags.id)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86)
|
|
||||||
static void
|
|
||||||
test_bcj(void)
|
|
||||||
{
|
|
||||||
// Test 1
|
|
||||||
known_flags.id = LZMA_FILTER_X86;
|
|
||||||
known_flags.options = NULL;
|
|
||||||
|
|
||||||
expect(!encode(2));
|
|
||||||
expect(!decode(2));
|
|
||||||
expect(decoded_flags.options == NULL);
|
|
||||||
|
|
||||||
// Test 2
|
|
||||||
lzma_options_bcj options;
|
|
||||||
options.start_offset = 0;
|
|
||||||
known_flags.options = &options;
|
|
||||||
expect(!encode(2));
|
|
||||||
expect(!decode(2));
|
|
||||||
expect(decoded_flags.options == NULL);
|
|
||||||
|
|
||||||
// Test 3
|
|
||||||
options.start_offset = 123456;
|
|
||||||
known_flags.options = &options;
|
|
||||||
expect(!encode(6));
|
|
||||||
expect(!decode(6));
|
|
||||||
expect(decoded_flags.options != NULL);
|
|
||||||
|
|
||||||
lzma_options_bcj *decoded = decoded_flags.options;
|
|
||||||
expect(decoded->start_offset == options.start_offset);
|
|
||||||
|
|
||||||
free(decoded);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA)
|
|
||||||
static void
|
|
||||||
test_delta(void)
|
|
||||||
{
|
|
||||||
// Test 1
|
|
||||||
known_flags.id = LZMA_FILTER_DELTA;
|
|
||||||
known_flags.options = NULL;
|
|
||||||
expect(encode(99));
|
|
||||||
|
|
||||||
// Test 2
|
|
||||||
lzma_options_delta options = {
|
|
||||||
.type = LZMA_DELTA_TYPE_BYTE,
|
|
||||||
.dist = 0
|
|
||||||
};
|
|
||||||
known_flags.options = &options;
|
|
||||||
expect(encode(99));
|
|
||||||
|
|
||||||
// Test 3
|
|
||||||
options.dist = LZMA_DELTA_DIST_MIN;
|
|
||||||
expect(!encode(3));
|
|
||||||
expect(!decode(3));
|
|
||||||
expect(((lzma_options_delta *)(decoded_flags.options))->dist
|
|
||||||
== options.dist);
|
|
||||||
|
|
||||||
free(decoded_flags.options);
|
|
||||||
|
|
||||||
// Test 4
|
|
||||||
options.dist = LZMA_DELTA_DIST_MAX;
|
|
||||||
expect(!encode(3));
|
|
||||||
expect(!decode(3));
|
|
||||||
expect(((lzma_options_delta *)(decoded_flags.options))->dist
|
|
||||||
== options.dist);
|
|
||||||
|
|
||||||
free(decoded_flags.options);
|
|
||||||
|
|
||||||
// Test 5
|
|
||||||
options.dist = LZMA_DELTA_DIST_MAX + 1;
|
|
||||||
expect(encode(99));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
#ifdef HAVE_FILTER_LZMA
|
|
||||||
static void
|
|
||||||
validate_lzma(void)
|
|
||||||
{
|
|
||||||
const lzma_options_lzma *known = known_flags.options;
|
|
||||||
const lzma_options_lzma *decoded = decoded_flags.options;
|
|
||||||
|
|
||||||
expect(known->dictionary_size <= decoded->dictionary_size);
|
|
||||||
|
|
||||||
if (known->dictionary_size == 1)
|
|
||||||
expect(decoded->dictionary_size == 1);
|
|
||||||
else
|
|
||||||
expect(known->dictionary_size + known->dictionary_size / 2
|
|
||||||
> decoded->dictionary_size);
|
|
||||||
|
|
||||||
expect(known->literal_context_bits == decoded->literal_context_bits);
|
|
||||||
expect(known->literal_pos_bits == decoded->literal_pos_bits);
|
|
||||||
expect(known->pos_bits == decoded->pos_bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_lzma(void)
|
|
||||||
{
|
|
||||||
// Test 1
|
|
||||||
known_flags.id = LZMA_FILTER_LZMA1;
|
|
||||||
known_flags.options = NULL;
|
|
||||||
expect(encode(99));
|
|
||||||
|
|
||||||
// Test 2
|
|
||||||
lzma_options_lzma options = {
|
|
||||||
.dictionary_size = 0,
|
|
||||||
.literal_context_bits = 0,
|
|
||||||
.literal_pos_bits = 0,
|
|
||||||
.pos_bits = 0,
|
|
||||||
.preset_dictionary = NULL,
|
|
||||||
.preset_dictionary_size = 0,
|
|
||||||
.mode = LZMA_MODE_INVALID,
|
|
||||||
.fast_bytes = 0,
|
|
||||||
.match_finder = LZMA_MF_INVALID,
|
|
||||||
.match_finder_cycles = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test 3 (empty dictionary not allowed)
|
|
||||||
known_flags.options = &options;
|
|
||||||
expect(encode(99));
|
|
||||||
|
|
||||||
// Test 4 (brute-force test some valid dictionary sizes)
|
|
||||||
options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN;
|
|
||||||
while (options.dictionary_size != LZMA_DICTIONARY_SIZE_MAX) {
|
|
||||||
if (++options.dictionary_size == 5000)
|
|
||||||
options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX - 5;
|
|
||||||
|
|
||||||
expect(!encode(4));
|
|
||||||
expect(!decode(4));
|
|
||||||
validate_lzma();
|
|
||||||
|
|
||||||
free(decoded_flags.options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test 5 (too big dictionary size)
|
// Next encode the filter flags for the provided filter
|
||||||
options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX + 1;
|
assert_lzma_ret(lzma_filter_flags_encode(filter, encoded_out,
|
||||||
expect(encode(99));
|
&out_pos, size), LZMA_OK);
|
||||||
|
assert_uint_eq(size, out_pos);
|
||||||
|
// Next decode the vli for the filter ID and verify it matches
|
||||||
|
// the expected filter id
|
||||||
|
size_t filter_id_vli_size = 0;
|
||||||
|
lzma_vli filter_id = 0;
|
||||||
|
assert_lzma_ret(lzma_vli_decode(&filter_id, NULL, encoded_out,
|
||||||
|
&filter_id_vli_size, size), LZMA_OK);
|
||||||
|
assert_uint_eq(filter->id, filter_id);
|
||||||
|
|
||||||
// Test 6 (brute-force test lc/lp/pb)
|
// Next decode the size of properites and ensure it equals
|
||||||
options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN;
|
// the expected size
|
||||||
for (uint32_t lc = LZMA_LITERAL_CONTEXT_BITS_MIN;
|
// Expected size should be:
|
||||||
lc <= LZMA_LITERAL_CONTEXT_BITS_MAX; ++lc) {
|
// total filter flag length - size of filter id VLI + size of
|
||||||
for (uint32_t lp = LZMA_LITERAL_POS_BITS_MIN;
|
// property size VLI
|
||||||
lp <= LZMA_LITERAL_POS_BITS_MAX; ++lp) {
|
// Not verifying the contents of Filter Properties since
|
||||||
for (uint32_t pb = LZMA_POS_BITS_MIN;
|
// that belongs in a different test
|
||||||
pb <= LZMA_POS_BITS_MAX; ++pb) {
|
size_t size_of_properties_vli_size = 0;
|
||||||
if (lc + lp > LZMA_LITERAL_BITS_MAX)
|
lzma_vli size_of_properties = 0;
|
||||||
continue;
|
assert_lzma_ret(lzma_vli_decode(&size_of_properties, NULL,
|
||||||
|
encoded_out + filter_id_vli_size,
|
||||||
|
&size_of_properties_vli_size, size), LZMA_OK);
|
||||||
|
assert_uint_eq(size - (size_of_properties_vli_size +
|
||||||
|
filter_id_vli_size), size_of_properties);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
options.literal_context_bits = lc;
|
|
||||||
options.literal_pos_bits = lp;
|
|
||||||
options.pos_bits = pb;
|
|
||||||
|
|
||||||
expect(!encode(4));
|
static void
|
||||||
expect(!decode(4));
|
test_lzma_filter_flags_encode(void)
|
||||||
validate_lzma();
|
{
|
||||||
|
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
|
||||||
|
assert_skip("Encoder or decoder support disabled");
|
||||||
|
#else
|
||||||
|
// No test for LZMA1 since the xz format does not support LZMA1
|
||||||
|
// and so the flags cannot be encoded for that filter
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||||
|
// Test with NULL options that should fail
|
||||||
|
lzma_options_lzma *options = lzma2_filter.options;
|
||||||
|
lzma2_filter.options = NULL;
|
||||||
|
verify_filter_flags_encode(&lzma2_filter, false);
|
||||||
|
// Place options back in the filter, and test should pass
|
||||||
|
lzma2_filter.options = options;
|
||||||
|
verify_filter_flags_encode(&lzma2_filter, true);
|
||||||
|
}
|
||||||
|
|
||||||
free(decoded_flags.options);
|
lzma_options_bcj bcj_options = {
|
||||||
}
|
.start_offset = 200
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < ARRAY_SIZE(bcj_filters_encoders); i++) {
|
||||||
|
// NULL options should pass for bcj filters
|
||||||
|
verify_filter_flags_encode(&bcj_filters_encoders[i], true);
|
||||||
|
lzma_filter bcj_with_options = INIT_FILTER(
|
||||||
|
bcj_filters_encoders[i].id, &bcj_options);
|
||||||
|
verify_filter_flags_encode(&bcj_with_options, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||||
|
lzma_options_delta delta_ops_below_min = {
|
||||||
|
.type = LZMA_DELTA_TYPE_BYTE,
|
||||||
|
.dist = LZMA_DELTA_DIST_MIN - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
lzma_options_delta delta_ops_above_max = {
|
||||||
|
.type = LZMA_DELTA_TYPE_BYTE,
|
||||||
|
.dist = LZMA_DELTA_DIST_MAX + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
verify_filter_flags_encode(&delta_filter, true);
|
||||||
|
|
||||||
|
lzma_filter delta_filter_bad_options = INIT_FILTER(
|
||||||
|
LZMA_FILTER_DELTA, &delta_ops_below_min);
|
||||||
|
|
||||||
|
// Next test error case using minimum - 1 delta distance
|
||||||
|
verify_filter_flags_encode(&delta_filter_bad_options, false);
|
||||||
|
|
||||||
|
// Next test error case using maximum + 1 delta distance
|
||||||
|
delta_filter_bad_options.options = &delta_ops_above_max;
|
||||||
|
verify_filter_flags_encode(&delta_filter_bad_options, false);
|
||||||
|
|
||||||
|
// Next test null case
|
||||||
|
delta_filter_bad_options.options = NULL;
|
||||||
|
verify_filter_flags_encode(&delta_filter_bad_options, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test expected failing cases
|
||||||
|
lzma_filter bad_filter = INIT_FILTER(LZMA_FILTER_RESERVED_START,
|
||||||
|
NULL);
|
||||||
|
size_t out_pos = 0;
|
||||||
|
size_t out_size = LZMA_BLOCK_HEADER_SIZE_MAX;
|
||||||
|
uint8_t out[LZMA_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
|
||||||
|
|
||||||
|
// Filter id outside of valid range
|
||||||
|
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos,
|
||||||
|
out_size), LZMA_PROG_ERROR);
|
||||||
|
out_pos = 0;
|
||||||
|
bad_filter.id = LZMA_VLI_MAX + 1;
|
||||||
|
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos,
|
||||||
|
out_size), LZMA_PROG_ERROR);
|
||||||
|
out_pos = 0;
|
||||||
|
|
||||||
|
// Invalid filter id
|
||||||
|
bad_filter.id = 2;
|
||||||
|
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos,
|
||||||
|
out_size), LZMA_OPTIONS_ERROR);
|
||||||
|
out_pos = 0;
|
||||||
|
|
||||||
|
// Out size too small
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||||
|
uint32_t bad_size = 0;
|
||||||
|
|
||||||
|
// First test with 0 output size
|
||||||
|
assert_lzma_ret(lzma_filter_flags_encode(
|
||||||
|
&lzma2_filter, out, &out_pos, 0),
|
||||||
|
LZMA_PROG_ERROR);
|
||||||
|
|
||||||
|
// Next calculate the size needed to encode and
|
||||||
|
// use less than that
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&bad_size,
|
||||||
|
&lzma2_filter), LZMA_OK);
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_filter_flags_encode(
|
||||||
|
&lzma2_filter, out, &out_pos,
|
||||||
|
bad_size - 1), LZMA_PROG_ERROR);
|
||||||
|
out_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid options
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||||
|
bad_filter.id = LZMA_FILTER_DELTA;
|
||||||
|
// First test with NULL options
|
||||||
|
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out,
|
||||||
|
&out_pos, out_size), LZMA_PROG_ERROR);
|
||||||
|
out_pos = 0;
|
||||||
|
|
||||||
|
// Next test with invalid options
|
||||||
|
lzma_options_delta bad_options = {
|
||||||
|
.dist = LZMA_DELTA_DIST_MAX + 1,
|
||||||
|
.type = LZMA_DELTA_TYPE_BYTE
|
||||||
|
};
|
||||||
|
bad_filter.options = &bad_options;
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out,
|
||||||
|
&out_pos, out_size), LZMA_PROG_ERROR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function for test_lzma_filter_flags_decode.
|
||||||
|
// Encodes the filter_in without using lzma_filter_flags_encode.
|
||||||
|
// Leaves the specific assertions of filter_out options to the caller
|
||||||
|
// because it is agnostic to the type of options used in the call
|
||||||
|
#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
|
||||||
|
static void
|
||||||
|
verify_filter_flags_decode(lzma_filter *filter_in, lzma_filter *filter_out)
|
||||||
|
{
|
||||||
|
uint32_t total_size = 0;
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&total_size, filter_in),
|
||||||
|
LZMA_OK);
|
||||||
|
uint8_t *filter_flag_buffer = tuktest_malloc(total_size);
|
||||||
|
|
||||||
|
uint32_t properties_size = 0;
|
||||||
|
size_t out_pos = 0, in_pos = 0;
|
||||||
|
assert_lzma_ret(lzma_properties_size(&properties_size, filter_in),
|
||||||
|
LZMA_OK);
|
||||||
|
assert_lzma_ret(lzma_vli_encode(filter_in->id, NULL,
|
||||||
|
filter_flag_buffer, &out_pos, total_size), LZMA_OK);
|
||||||
|
assert_lzma_ret(lzma_vli_encode(properties_size, NULL,
|
||||||
|
filter_flag_buffer, &out_pos, total_size),
|
||||||
|
LZMA_OK);
|
||||||
|
assert_lzma_ret(lzma_properties_encode(filter_in,
|
||||||
|
filter_flag_buffer + out_pos), LZMA_OK);
|
||||||
|
assert_lzma_ret(lzma_filter_flags_decode(filter_out, NULL,
|
||||||
|
filter_flag_buffer, &in_pos, total_size),
|
||||||
|
LZMA_OK);
|
||||||
|
assert_uint_eq(filter_in->id, filter_out->id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_lzma_filter_flags_decode(void)
|
||||||
|
{
|
||||||
|
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
|
||||||
|
assert_skip("Encoder or decoder support disabled");
|
||||||
|
#else
|
||||||
|
// For each filter, only run the decoder test if both the encoder
|
||||||
|
// and decoder is enabled. This is because verify_filter_flags_decode
|
||||||
|
// uses lzma_filter_flags_size, which requires the encoder.
|
||||||
|
if (lzma_filter_decoder_is_supported(LZMA_FILTER_LZMA2) &&
|
||||||
|
lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||||
|
lzma_filter lzma2_decoded = INIT_FILTER(LZMA_FILTER_LZMA2,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
verify_filter_flags_decode(&lzma2_filter, &lzma2_decoded);
|
||||||
|
|
||||||
|
lzma_options_lzma *expected = lzma2_filter.options;
|
||||||
|
lzma_options_lzma *decoded = lzma2_decoded.options;
|
||||||
|
|
||||||
|
// Only the dictionary size is encoded and decoded
|
||||||
|
// so only compare those
|
||||||
|
assert_uint_eq(decoded->dict_size, expected->dict_size);
|
||||||
|
|
||||||
|
// The decoded options must be freed by the caller
|
||||||
|
free(decoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < ARRAY_SIZE(bcj_filters_decoders); i++) {
|
||||||
|
if (lzma_filter_encoder_is_supported(
|
||||||
|
bcj_filters_decoders[i].id)) {
|
||||||
|
lzma_filter bcj_decoded = INIT_FILTER(
|
||||||
|
bcj_filters_decoders[i].id, NULL);
|
||||||
|
|
||||||
|
lzma_filter bcj_encoded = INIT_FILTER(
|
||||||
|
bcj_filters_decoders[i].id, NULL);
|
||||||
|
|
||||||
|
// First test without options
|
||||||
|
verify_filter_flags_decode(&bcj_encoded,
|
||||||
|
&bcj_decoded);
|
||||||
|
assert_true(bcj_decoded.options == NULL);
|
||||||
|
|
||||||
|
// Next test with offset
|
||||||
|
lzma_options_bcj options = {
|
||||||
|
.start_offset = 200
|
||||||
|
};
|
||||||
|
|
||||||
|
bcj_encoded.options = &options;
|
||||||
|
verify_filter_flags_decode(&bcj_encoded,
|
||||||
|
&bcj_decoded);
|
||||||
|
lzma_options_bcj *decoded_ops = bcj_decoded.options;
|
||||||
|
assert_uint_eq(decoded_ops->start_offset,
|
||||||
|
options.start_offset);
|
||||||
|
free(decoded_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
if (lzma_filter_decoder_is_supported(LZMA_FILTER_DELTA) &&
|
||||||
main(void)
|
lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||||
|
lzma_filter delta_decoded = INIT_FILTER(LZMA_FILTER_DELTA,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
verify_filter_flags_decode(&delta_filter, &delta_decoded);
|
||||||
|
lzma_options_delta *expected = delta_filter.options;
|
||||||
|
lzma_options_delta *decoded = delta_decoded.options;
|
||||||
|
assert_uint_eq(expected->dist, decoded->dist);
|
||||||
|
assert_uint_eq(expected->type, decoded->type);
|
||||||
|
|
||||||
|
free(decoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test expected failing cases
|
||||||
|
uint8_t bad_encoded_filter[LZMA_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
lzma_filter bad_filter;
|
||||||
|
|
||||||
|
// Filter outside of valid range
|
||||||
|
lzma_vli bad_filter_id = LZMA_FILTER_RESERVED_START;
|
||||||
|
size_t bad_encoded_out_pos = 0;
|
||||||
|
size_t in_pos = 0;
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_vli_encode(bad_filter_id, NULL,
|
||||||
|
bad_encoded_filter, &bad_encoded_out_pos,
|
||||||
|
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK);
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL,
|
||||||
|
bad_encoded_filter, &in_pos,
|
||||||
|
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_DATA_ERROR);
|
||||||
|
|
||||||
|
bad_encoded_out_pos = 0;
|
||||||
|
in_pos = 0;
|
||||||
|
|
||||||
|
// Invalid filter Id
|
||||||
|
bad_filter_id = 2;
|
||||||
|
bad_encoded_out_pos = 0;
|
||||||
|
in_pos = 0;
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_vli_encode(bad_filter_id, NULL,
|
||||||
|
bad_encoded_filter, &bad_encoded_out_pos,
|
||||||
|
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK);
|
||||||
|
|
||||||
|
// Next encode propery size of 0
|
||||||
|
assert_lzma_ret(lzma_vli_encode(0, NULL,
|
||||||
|
bad_encoded_filter, &bad_encoded_out_pos,
|
||||||
|
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK);
|
||||||
|
// Decode should fail on bad filter id
|
||||||
|
assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL,
|
||||||
|
bad_encoded_filter, &in_pos,
|
||||||
|
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OPTIONS_ERROR);
|
||||||
|
bad_encoded_out_pos = 0;
|
||||||
|
in_pos = 0;
|
||||||
|
|
||||||
|
// Outsize too small
|
||||||
|
// Encode the lzma2 filter normally, but then set
|
||||||
|
// the out size when decoding as too small
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2) &&
|
||||||
|
lzma_filter_decoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||||
|
uint32_t filter_flag_size = 0;
|
||||||
|
assert_lzma_ret(lzma_filter_flags_size(&filter_flag_size,
|
||||||
|
&lzma2_filter), LZMA_OK);
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_filter_flags_encode(&lzma2_filter,
|
||||||
|
bad_encoded_filter, &bad_encoded_out_pos,
|
||||||
|
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK);
|
||||||
|
|
||||||
|
assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL,
|
||||||
|
bad_encoded_filter, &in_pos,
|
||||||
|
filter_flag_size - 1), LZMA_DATA_ERROR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int
|
||||||
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86)
|
tuktest_start(argc, argv);
|
||||||
test_bcj();
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA)
|
|
||||||
test_delta();
|
|
||||||
#endif
|
|
||||||
// #ifdef HAVE_FILTER_LZMA
|
|
||||||
// test_lzma();
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
lzma_end(&strm);
|
#ifdef HAVE_ENCODERS
|
||||||
|
// Only init filter options if encoder is supported because decoder
|
||||||
|
// tests requires encoder support, so the decoder tests will only
|
||||||
|
// run if for a given filter both the encoder and decoder are enabled.
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA1)) {
|
||||||
|
lzma_options_lzma *options = tuktest_malloc(
|
||||||
|
sizeof(lzma_options_lzma));
|
||||||
|
lzma_lzma_preset(options, LZMA_PRESET_DEFAULT);
|
||||||
|
lzma1_filter.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||||
|
lzma_options_lzma *options = tuktest_malloc(
|
||||||
|
sizeof(lzma_options_lzma));
|
||||||
|
lzma_lzma_preset(options, LZMA_PRESET_DEFAULT);
|
||||||
|
lzma2_filter.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||||
|
lzma_options_delta *options = tuktest_malloc(
|
||||||
|
sizeof(lzma_options_delta));
|
||||||
|
options->dist = LZMA_DELTA_DIST_MIN;
|
||||||
|
options->type = LZMA_DELTA_TYPE_BYTE;
|
||||||
|
delta_filter.options = options;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tuktest_run(test_lzma_filter_flags_size);
|
||||||
|
tuktest_run(test_lzma_filter_flags_encode);
|
||||||
|
tuktest_run(test_lzma_filter_flags_decode);
|
||||||
|
return tuktest_end();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue