1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file test_index_hash.c
4 /// \brief Tests src/liblzma/common/index_hash.c API functions
6 /// \note No test included for lzma_index_hash_end since it
7 /// would be trivial unless tested for memory leaks
8 /// with something like valgrind
12 // This file has been put into the public domain.
13 // You can do whatever you want with this file.
15 ///////////////////////////////////////////////////////////////////////////////
19 // Needed for UNPADDED_SIZE_MIN and UNPADDED_SIZE_MAX macro definitions
20 // and index_size and vli_ceil4 helper functions
21 #include "common/index.h"
25 test_lzma_index_hash_init(void)
28 assert_skip("Decoder support disabled");
30 // First test with NULL index_hash.
31 // This should create a fresh index_hash.
32 lzma_index_hash
*index_hash
= lzma_index_hash_init(NULL
, NULL
);
33 assert_true(index_hash
!= NULL
);
35 // Next test with non-NULL index_hash.
36 lzma_index_hash
*second_hash
= lzma_index_hash_init(index_hash
, NULL
);
38 // It should not create a new index_hash pointer.
39 // Instead it must just re-init the first index_hash.
40 assert_true(index_hash
== second_hash
);
42 lzma_index_hash_end(index_hash
, NULL
);
48 test_lzma_index_hash_append(void)
51 assert_skip("Decoder support disabled");
53 // Test all invalid parameters
54 assert_lzma_ret(lzma_index_hash_append(NULL
, 0, 0),
57 // Test NULL index_hash
58 assert_lzma_ret(lzma_index_hash_append(NULL
, UNPADDED_SIZE_MIN
,
59 LZMA_VLI_MAX
), LZMA_PROG_ERROR
);
61 // Test with invalid Unpadded Size
62 lzma_index_hash
*index_hash
= lzma_index_hash_init(NULL
, NULL
);
63 assert_true(index_hash
!= NULL
);
64 assert_lzma_ret(lzma_index_hash_append(index_hash
,
65 UNPADDED_SIZE_MIN
- 1, LZMA_VLI_MAX
),
68 // Test with invalid Uncompressed Size
69 assert_lzma_ret(lzma_index_hash_append(index_hash
,
70 UNPADDED_SIZE_MIN
, LZMA_VLI_MAX
+ 1),
73 // First append a Record describing a small Block.
74 // This should succeed.
75 assert_lzma_ret(lzma_index_hash_append(index_hash
,
76 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
78 // Append another small Record.
79 assert_lzma_ret(lzma_index_hash_append(index_hash
,
80 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
82 // Append a Record that would cause the compressed size to grow
84 assert_lzma_ret(lzma_index_hash_append(index_hash
,
85 UNPADDED_SIZE_MAX
, 1), LZMA_DATA_ERROR
);
87 lzma_index_hash_end(index_hash
, NULL
);
92 #if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
93 // Fill an index_hash with unpadded and uncompressed VLIs
94 // by calling lzma_index_hash_append
96 fill_index_hash(lzma_index_hash
*index_hash
, const lzma_vli
*unpadded_sizes
,
97 const lzma_vli
*uncomp_sizes
, uint32_t block_count
)
99 for (uint32_t i
= 0; i
< block_count
; ++i
)
100 assert_lzma_ret(lzma_index_hash_append(index_hash
,
101 unpadded_sizes
[i
], uncomp_sizes
[i
]), LZMA_OK
);
105 // Set the contents of buf to the expected Index based on the
106 // .xz specification. This needs the unpadded and uncompressed VLIs
107 // to correctly create the Index.
109 generate_index(uint8_t *buf
, const lzma_vli
*unpadded_sizes
,
110 const lzma_vli
*uncomp_sizes
, uint32_t block_count
,
111 size_t index_max_size
)
116 // First set Index Indicator
117 buf
[out_pos
++] = INDEX_INDICATOR
;
119 // Next write out Number of Records
120 assert_lzma_ret(lzma_vli_encode(block_count
, &in_pos
, buf
,
121 &out_pos
, index_max_size
), LZMA_STREAM_END
);
123 // Next write out each Record.
124 // A Record consists of Unpadded Size and Uncompressed Size
125 // written next to each other as VLIs.
126 for (uint32_t i
= 0; i
< block_count
; ++i
) {
128 assert_lzma_ret(lzma_vli_encode(unpadded_sizes
[i
], &in_pos
,
129 buf
, &out_pos
, index_max_size
), LZMA_STREAM_END
);
131 assert_lzma_ret(lzma_vli_encode(uncomp_sizes
[i
], &in_pos
,
132 buf
, &out_pos
, index_max_size
), LZMA_STREAM_END
);
136 lzma_vli rounded_out_pos
= vli_ceil4(out_pos
);
137 memzero(buf
+ out_pos
, rounded_out_pos
- out_pos
);
138 out_pos
= rounded_out_pos
;
141 write32le(buf
+ out_pos
, lzma_crc32(buf
, out_pos
, 0));
144 assert_uint_eq(out_pos
, index_max_size
);
150 test_lzma_index_hash_decode(void)
152 #if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
153 assert_skip("Encoder or decoder support disabled");
155 lzma_index_hash
*index_hash
= lzma_index_hash_init(NULL
, NULL
);
156 assert_true(index_hash
!= NULL
);
160 // Six valid values for the Unpadded Size fields in an Index
161 const lzma_vli unpadded_sizes
[6] = {
170 // Six valid values for the Uncompressed Size fields in an Index
171 const lzma_vli uncomp_sizes
[6] = {
180 // Add two Records to an index_hash
181 fill_index_hash(index_hash
, unpadded_sizes
, uncomp_sizes
, 2);
183 const lzma_vli size_two_records
= lzma_index_hash_size(index_hash
);
184 assert_uint(size_two_records
, >, 0);
185 uint8_t *index_two_records
= tuktest_malloc(size_two_records
);
187 generate_index(index_two_records
, unpadded_sizes
, uncomp_sizes
, 2,
190 // First test for basic buffer size error
191 in_pos
= size_two_records
+ 1;
192 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
193 index_two_records
, &in_pos
,
194 size_two_records
), LZMA_BUF_ERROR
);
196 // Next test for invalid Index Indicator
198 index_two_records
[0] ^= 1;
199 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
200 index_two_records
, &in_pos
,
201 size_two_records
), LZMA_DATA_ERROR
);
202 index_two_records
[0] ^= 1;
204 // Next verify the index_hash as expected
206 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
207 index_two_records
, &in_pos
,
208 size_two_records
), LZMA_STREAM_END
);
210 // Next test an index_hash with three Records
211 index_hash
= lzma_index_hash_init(index_hash
, NULL
);
212 fill_index_hash(index_hash
, unpadded_sizes
, uncomp_sizes
, 3);
214 const lzma_vli size_three_records
= lzma_index_hash_size(
216 assert_uint(size_three_records
, >, 0);
217 uint8_t *index_three_records
= tuktest_malloc(size_three_records
);
219 generate_index(index_three_records
, unpadded_sizes
, uncomp_sizes
,
220 3, size_three_records
);
223 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
224 index_three_records
, &in_pos
,
225 size_three_records
), LZMA_STREAM_END
);
227 // Next test an index_hash with five Records
228 index_hash
= lzma_index_hash_init(index_hash
, NULL
);
229 fill_index_hash(index_hash
, unpadded_sizes
, uncomp_sizes
, 5);
231 const lzma_vli size_five_records
= lzma_index_hash_size(
233 assert_uint(size_five_records
, >, 0);
234 uint8_t *index_five_records
= tuktest_malloc(size_five_records
);
236 generate_index(index_five_records
, unpadded_sizes
, uncomp_sizes
, 5,
239 // Instead of testing all input at once, give input
240 // one byte at a time
242 for (lzma_vli i
= 0; i
< size_five_records
- 1; ++i
) {
243 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
244 index_five_records
, &in_pos
, in_pos
+ 1),
248 // Last byte should return LZMA_STREAM_END
249 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
250 index_five_records
, &in_pos
,
251 in_pos
+ 1), LZMA_STREAM_END
);
253 // Next test if the index_hash is given an incorrect Unpadded
254 // Size. Should detect and report LZMA_DATA_ERROR
255 index_hash
= lzma_index_hash_init(index_hash
, NULL
);
256 fill_index_hash(index_hash
, unpadded_sizes
, uncomp_sizes
, 5);
257 // The sixth Record will have an invalid Unpadded Size
258 assert_lzma_ret(lzma_index_hash_append(index_hash
,
259 unpadded_sizes
[5] + 1,
260 uncomp_sizes
[5]), LZMA_OK
);
262 const lzma_vli size_six_records
= lzma_index_hash_size(
265 assert_uint(size_six_records
, >, 0);
266 uint8_t *index_six_records
= tuktest_malloc(size_six_records
);
268 generate_index(index_six_records
, unpadded_sizes
, uncomp_sizes
, 6,
271 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
272 index_six_records
, &in_pos
,
273 size_six_records
), LZMA_DATA_ERROR
);
275 // Next test if the Index is corrupt (invalid CRC32).
276 // Should detect and report LZMA_DATA_ERROR
277 index_hash
= lzma_index_hash_init(index_hash
, NULL
);
278 fill_index_hash(index_hash
, unpadded_sizes
, uncomp_sizes
, 2);
280 index_two_records
[size_two_records
- 1] ^= 1;
283 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
284 index_two_records
, &in_pos
,
285 size_two_records
), LZMA_DATA_ERROR
);
287 // Next test with Index and index_hash struct not matching
289 index_hash
= lzma_index_hash_init(index_hash
, NULL
);
290 fill_index_hash(index_hash
, unpadded_sizes
, uncomp_sizes
, 2);
291 // Recalculate Index with invalid Unpadded Size
292 const lzma_vli unpadded_sizes_invalid
[2] = {
294 unpadded_sizes
[1] + 1
297 generate_index(index_two_records
, unpadded_sizes_invalid
,
298 uncomp_sizes
, 2, size_two_records
);
301 assert_lzma_ret(lzma_index_hash_decode(index_hash
,
302 index_two_records
, &in_pos
,
303 size_two_records
), LZMA_DATA_ERROR
);
305 lzma_index_hash_end(index_hash
, NULL
);
311 test_lzma_index_hash_size(void)
313 #ifndef HAVE_DECODERS
314 assert_skip("Decoder support disabled");
316 lzma_index_hash
*index_hash
= lzma_index_hash_init(NULL
, NULL
);
317 assert_true(index_hash
!= NULL
);
319 // First test empty index_hash
320 // Expected size should be:
321 // Index Indicator - 1 byte
322 // Number of Records - 1 byte
323 // List of Records - 0 bytes
324 // Index Padding - 2 bytes
327 assert_uint_eq(lzma_index_hash_size(index_hash
), 8);
329 // Append a Record describing a small Block to the index_hash
330 assert_lzma_ret(lzma_index_hash_append(index_hash
,
331 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
333 // Expected size should be:
334 // Index Indicator - 1 byte
335 // Number of Records - 1 byte
336 // List of Records - 2 bytes
337 // Index Padding - 0 bytes
340 lzma_vli expected_size
= 8;
341 assert_uint_eq(lzma_index_hash_size(index_hash
), expected_size
);
343 // Append additional small Record
344 assert_lzma_ret(lzma_index_hash_append(index_hash
,
345 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
347 // Expected size should be:
348 // Index Indicator - 1 byte
349 // Number of Records - 1 byte
350 // List of Records - 4 bytes
351 // Index Padding - 2 bytes
355 assert_uint_eq(lzma_index_hash_size(index_hash
), expected_size
);
357 // Append a larger Record to the index_hash (3 bytes for each VLI)
358 const lzma_vli three_byte_vli
= 0x10000;
359 assert_lzma_ret(lzma_index_hash_append(index_hash
,
360 three_byte_vli
, three_byte_vli
), LZMA_OK
);
362 // Expected size should be:
363 // Index Indicator - 1 byte
364 // Number of Records - 1 byte
365 // List of Records - 10 bytes
366 // Index Padding - 0 bytes
370 assert_uint_eq(lzma_index_hash_size(index_hash
), expected_size
);
372 lzma_index_hash_end(index_hash
, NULL
);
378 main(int argc
, char **argv
)
380 tuktest_start(argc
, argv
);
381 tuktest_run(test_lzma_index_hash_init
);
382 tuktest_run(test_lzma_index_hash_append
);
383 tuktest_run(test_lzma_index_hash_decode
);
384 tuktest_run(test_lzma_index_hash_size
);
385 return tuktest_end();