7ed9d943b3
Half of developers were already forgetting to use these functions, which could have caused total breakage in some future liblzma version or even now if --enable-small was used. Now liblzma uses pthread_once() to do the initializations unless it has been built with --disable-threads which make these initializations thread-unsafe. When --enable-small isn't used, liblzma currently gets needlessly linked against libpthread (on systems that have it). While it is stupid for now, liblzma will need threads in future anyway, so this stupidity will be temporary only. When --enable-small is used, different code CRC32 and CRC64 is now used than without --enable-small. This made the resulting binary slightly smaller, but the main reason was to clean it up and to handle the lack of lzma_init_check(). The pkg-config file lzma.pc was renamed to liblzma.pc. I'm not sure if it works correctly and portably for static linking (Libs.private includes -pthread or other operating system specific flags). Hopefully someone complains if it is bad. lzma_rc_prices[] is now included as a precomputed array even with --enable-small. It's just 128 bytes now that it uses uint8_t instead of uint32_t. Smaller array seemed to be at least as fast as the more bloated uint32_t array on x86; hopefully it's not bad on other architectures.
248 lines
6.2 KiB
C
248 lines
6.2 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
/// \file test_block_header.c
|
|
/// \brief Tests Block Header coders
|
|
//
|
|
// Copyright (C) 2007 Lasse Collin
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2.1 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#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_filter filters_none[1] = {
|
|
{
|
|
.id = LZMA_VLI_UNKNOWN,
|
|
},
|
|
};
|
|
|
|
|
|
static lzma_filter filters_one[2] = {
|
|
{
|
|
.id = LZMA_FILTER_LZMA2,
|
|
.options = &opt_lzma,
|
|
}, {
|
|
.id = LZMA_VLI_UNKNOWN,
|
|
}
|
|
};
|
|
|
|
|
|
static lzma_filter filters_four[5] = {
|
|
{
|
|
.id = LZMA_FILTER_X86,
|
|
.options = NULL,
|
|
}, {
|
|
.id = LZMA_FILTER_X86,
|
|
.options = NULL,
|
|
}, {
|
|
.id = LZMA_FILTER_X86,
|
|
.options = NULL,
|
|
}, {
|
|
.id = LZMA_FILTER_LZMA2,
|
|
.options = &opt_lzma,
|
|
}, {
|
|
.id = LZMA_VLI_UNKNOWN,
|
|
}
|
|
};
|
|
|
|
|
|
static lzma_filter filters_five[6] = {
|
|
{
|
|
.id = LZMA_FILTER_X86,
|
|
.options = NULL,
|
|
}, {
|
|
.id = LZMA_FILTER_X86,
|
|
.options = NULL,
|
|
}, {
|
|
.id = LZMA_FILTER_X86,
|
|
.options = NULL,
|
|
}, {
|
|
.id = LZMA_FILTER_X86,
|
|
.options = NULL,
|
|
}, {
|
|
.id = LZMA_FILTER_LZMA2,
|
|
.options = &opt_lzma,
|
|
}, {
|
|
.id = LZMA_VLI_UNKNOWN,
|
|
}
|
|
};
|
|
|
|
|
|
static void
|
|
code(void)
|
|
{
|
|
expect(lzma_block_header_encode(&known_options, buf) == LZMA_OK);
|
|
|
|
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
|
memcrap(filters, sizeof(filters));
|
|
memcrap(&decoded_options, sizeof(decoded_options));
|
|
|
|
decoded_options.header_size = known_options.header_size;
|
|
decoded_options.check = known_options.check;
|
|
decoded_options.filters = filters;
|
|
expect(lzma_block_header_decode(&decoded_options, NULL, buf)
|
|
== LZMA_OK);
|
|
|
|
expect(known_options.compressed_size
|
|
== decoded_options.compressed_size);
|
|
expect(known_options.uncompressed_size
|
|
== decoded_options.uncompressed_size);
|
|
|
|
for (size_t i = 0; known_options.filters[i].id
|
|
!= LZMA_VLI_UNKNOWN; ++i)
|
|
expect(known_options.filters[i].id == 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,
|
|
};
|
|
|
|
expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
|
|
|
|
known_options.filters = filters_none;
|
|
expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
|
|
|
|
known_options.filters = filters_five;
|
|
expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
|
|
|
|
known_options.filters = filters_one;
|
|
expect(lzma_block_header_size(&known_options) == LZMA_OK);
|
|
|
|
known_options.check = 999; // Some invalid value, which gets ignored.
|
|
expect(lzma_block_header_size(&known_options) == LZMA_OK);
|
|
|
|
known_options.compressed_size = 5;
|
|
expect(lzma_block_header_size(&known_options) == LZMA_OK);
|
|
|
|
known_options.compressed_size = 0; // Cannot be zero.
|
|
expect(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;
|
|
expect(lzma_block_header_size(&known_options) == LZMA_OK);
|
|
|
|
known_options.compressed_size = LZMA_VLI_UNKNOWN;
|
|
known_options.uncompressed_size = 0;
|
|
expect(lzma_block_header_size(&known_options) == LZMA_OK);
|
|
|
|
known_options.uncompressed_size = LZMA_VLI_MAX + 1;
|
|
expect(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,
|
|
};
|
|
|
|
expect(lzma_block_header_size(&known_options) == LZMA_OK);
|
|
code();
|
|
|
|
known_options.compressed_size = 123456;
|
|
known_options.uncompressed_size = 234567;
|
|
expect(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,
|
|
};
|
|
|
|
expect(lzma_block_header_size(&known_options) == LZMA_OK);
|
|
known_options.header_size += 4;
|
|
expect(lzma_block_header_encode(&known_options, buf) == LZMA_OK);
|
|
|
|
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
|
decoded_options.header_size = known_options.header_size;
|
|
decoded_options.check = known_options.check;
|
|
decoded_options.filters = filters;
|
|
|
|
// Wrong size
|
|
++buf[0];
|
|
expect(lzma_block_header_decode(&decoded_options, NULL, buf)
|
|
== LZMA_PROG_ERROR);
|
|
--buf[0];
|
|
|
|
// Wrong CRC32
|
|
buf[known_options.header_size - 1] ^= 1;
|
|
expect(lzma_block_header_decode(&decoded_options, NULL, buf)
|
|
== LZMA_DATA_ERROR);
|
|
buf[known_options.header_size - 1] ^= 1;
|
|
|
|
// Unsupported filter
|
|
// NOTE: This may need updating when new IDs become supported.
|
|
buf[2] ^= 0x1F;
|
|
integer_write_32(buf + known_options.header_size - 4,
|
|
lzma_crc32(buf, known_options.header_size - 4, 0));
|
|
expect(lzma_block_header_decode(&decoded_options, NULL, buf)
|
|
== LZMA_OPTIONS_ERROR);
|
|
buf[2] ^= 0x1F;
|
|
|
|
// Non-nul Padding
|
|
buf[known_options.header_size - 4 - 1] ^= 1;
|
|
integer_write_32(buf + known_options.header_size - 4,
|
|
lzma_crc32(buf, known_options.header_size - 4, 0));
|
|
expect(lzma_block_header_decode(&decoded_options, NULL, buf)
|
|
== LZMA_OPTIONS_ERROR);
|
|
buf[known_options.header_size - 4 - 1] ^= 1;
|
|
}
|
|
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
succeed(lzma_lzma_preset(&opt_lzma, 1));
|
|
|
|
test1();
|
|
test2();
|
|
test3();
|
|
|
|
return 0;
|
|
}
|