1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file test_block_header.c
4 /// \brief Tests Block Header coders
6 // Copyright (C) 2007 Lasse Collin
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 ///////////////////////////////////////////////////////////////////////////////
23 static uint8_t buffer[4096];
24 static lzma_stream strm = LZMA_STREAM_INIT;
25 static lzma_options_block known_options;
26 static lzma_options_block decoded_options;
28 // We want to test zero, one, and two filters in the chain.
30 static const lzma_options_filter filters_none[1] = {
32 .id = LZMA_VLI_VALUE_UNKNOWN,
37 static const lzma_options_filter filters_powerpc[2] = {
39 .id = LZMA_FILTER_POWERPC,
42 .id = LZMA_VLI_VALUE_UNKNOWN,
47 static const lzma_options_delta options_delta = {
51 static const lzma_options_filter filters_delta[3] = {
53 .id = LZMA_FILTER_DELTA,
54 .options = (void *)(&options_delta),
56 .id = LZMA_FILTER_COPY,
59 .id = LZMA_VLI_VALUE_UNKNOWN,
66 free_decoded_options(void)
68 for (size_t i = 0; i < sizeof(decoded_options.filters)
69 / sizeof(decoded_options.filters[0]); ++i) {
70 free(decoded_options.filters[i].options);
71 decoded_options.filters[i].options = NULL;
77 encode(uint32_t header_size)
79 memcrap(buffer, sizeof(buffer));
81 if (lzma_block_header_size(&known_options) != LZMA_OK)
84 if (known_options.header_size != header_size)
87 if (lzma_block_header_encode(buffer, &known_options) != LZMA_OK)
95 decode_ret(uint32_t header_size, lzma_ret ret_ok)
97 memcrap(&decoded_options, sizeof(decoded_options));
98 decoded_options.has_crc32 = known_options.has_crc32;
100 expect(lzma_block_header_decoder(&strm, &decoded_options) == LZMA_OK);
102 const bool ret = decoder_loop_ret(&strm, buffer, header_size, ret_ok);
103 free_decoded_options();
109 decode(uint32_t header_size)
111 memcrap(&decoded_options, sizeof(decoded_options));
112 decoded_options.has_crc32 = known_options.has_crc32;
114 expect(lzma_block_header_decoder(&strm, &decoded_options) == LZMA_OK);
116 const bool ret = decoder_loop(&strm, buffer, header_size);
117 free_decoded_options();
121 if (known_options.has_eopm != decoded_options.has_eopm)
124 if (known_options.is_metadata != decoded_options.is_metadata)
127 if (known_options.compressed_size == LZMA_VLI_VALUE_UNKNOWN
128 && known_options.compressed_reserve != 0) {
129 if (decoded_options.compressed_size != 0)
131 } else if (known_options.compressed_size
132 != decoded_options.compressed_size) {
136 if (known_options.uncompressed_size == LZMA_VLI_VALUE_UNKNOWN
137 && known_options.uncompressed_reserve != 0) {
138 if (decoded_options.uncompressed_size != 0)
140 } else if (known_options.uncompressed_size
141 != decoded_options.uncompressed_size) {
145 if (known_options.compressed_reserve != 0
146 && known_options.compressed_reserve
147 != decoded_options.compressed_reserve)
150 if (known_options.uncompressed_reserve != 0
151 && known_options.uncompressed_reserve
152 != decoded_options.uncompressed_reserve)
155 if (known_options.padding != decoded_options.padding)
163 code(uint32_t header_size)
165 return encode(header_size) || decode(header_size);
170 helper_loop(uint32_t unpadded_size, uint32_t multiple)
172 for (int i = 0; i <= LZMA_BLOCK_HEADER_PADDING_MAX; ++i) {
173 known_options.padding = i;
174 if (code(unpadded_size + i))
178 for (int i = 0 - LZMA_BLOCK_HEADER_PADDING_MAX - 1;
179 i <= LZMA_BLOCK_HEADER_PADDING_MAX + 1; ++i) {
180 known_options.alignment = i;
182 uint32_t size = unpadded_size;
183 while ((size + known_options.alignment) % multiple)
186 known_options.padding = LZMA_BLOCK_HEADER_PADDING_AUTO;
190 } while (++known_options.alignment
191 <= LZMA_BLOCK_HEADER_PADDING_MAX + 1);
198 helper(uint32_t unpadded_size, uint32_t multiple)
200 known_options.has_crc32 = false;
201 known_options.is_metadata = false;
202 if (helper_loop(unpadded_size, multiple))
205 known_options.has_crc32 = false;
206 known_options.is_metadata = true;
207 if (helper_loop(unpadded_size, multiple))
210 known_options.has_crc32 = true;
211 known_options.is_metadata = false;
212 if (helper_loop(unpadded_size + 4, multiple))
215 known_options.has_crc32 = true;
216 known_options.is_metadata = true;
217 if (helper_loop(unpadded_size + 4, multiple))
227 known_options = (lzma_options_block){
229 .compressed_size = LZMA_VLI_VALUE_UNKNOWN,
230 .uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
231 .compressed_reserve = 0,
232 .uncompressed_reserve = 0,
234 memcpy(known_options.filters, filters_none, sizeof(filters_none));
235 expect(!helper(2, 1));
237 memcpy(known_options.filters, filters_powerpc,
238 sizeof(filters_powerpc));
239 expect(!helper(3, 4));
241 memcpy(known_options.filters, filters_delta, sizeof(filters_delta));
242 expect(!helper(5, 1));
244 known_options.padding = LZMA_BLOCK_HEADER_PADDING_MAX + 1;
245 expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
250 test2_helper(uint32_t unpadded_size, uint32_t multiple)
252 known_options.has_eopm = true;
253 known_options.compressed_size = LZMA_VLI_VALUE_UNKNOWN;
254 known_options.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN;
255 known_options.compressed_reserve = 1;
256 known_options.uncompressed_reserve = 1;
257 expect(!helper(unpadded_size + 2, multiple));
259 known_options.compressed_reserve = LZMA_VLI_BYTES_MAX;
260 known_options.uncompressed_reserve = LZMA_VLI_BYTES_MAX;
261 expect(!helper(unpadded_size + 18, multiple));
263 known_options.compressed_size = 1234;
264 known_options.uncompressed_size = 2345;
265 expect(!helper(unpadded_size + 18, multiple));
267 known_options.compressed_reserve = 1;
268 known_options.uncompressed_reserve = 1;
269 expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
276 memcpy(known_options.filters, filters_none, sizeof(filters_none));
279 memcpy(known_options.filters, filters_powerpc,
280 sizeof(filters_powerpc));
283 memcpy(known_options.filters, filters_delta,
284 sizeof(filters_delta));
292 known_options = (lzma_options_block){
295 .is_metadata = false,
296 .compressed_size = LZMA_VLI_VALUE_UNKNOWN,
297 .uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
298 .compressed_reserve = 1,
299 .uncompressed_reserve = 1,
301 memcpy(known_options.filters, filters_none, sizeof(filters_none));
303 known_options.header_size = 3;
304 expect(lzma_block_header_encode(buffer, &known_options)
307 known_options.header_size = 4;
308 expect(lzma_block_header_encode(buffer, &known_options) == LZMA_OK);
310 known_options.header_size = 5;
311 expect(lzma_block_header_encode(buffer, &known_options)
314 // NOTE: This assumes that Filter ID 0x1F is not supported. Update
315 // this test to use some other ID if 0x1F becomes supported.
316 known_options.filters[0].id = 0x1F;
317 known_options.header_size = 5;
318 expect(lzma_block_header_encode(buffer, &known_options)
319 == LZMA_HEADER_ERROR);
326 known_options = (lzma_options_block){
329 .is_metadata = false,
330 .compressed_size = 0,
331 .uncompressed_size = 0,
332 .compressed_reserve = LZMA_VLI_BYTES_MAX,
333 .uncompressed_reserve = LZMA_VLI_BYTES_MAX,
336 memcpy(known_options.filters, filters_powerpc,
337 sizeof(filters_powerpc));
342 expect(!decode_ret(1, LZMA_HEADER_ERROR));
346 expect(decode_ret(21, LZMA_HEADER_ERROR));