Doc: Rename Doxygen HTML doc directory name liblzma => api.
[xz/debian.git] / tests / test_index.c
blobf63d2a79d594353af60ce123440f6ecbc921fc64
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file test_index.c
4 /// \brief Tests functions handling the lzma_index structure
5 ///
6 /// \todo Implement tests for lzma_file_info_decoder
7 //
8 // Authors: Jia Tan
9 // Lasse Collin
12 // This file has been put into the public domain.
13 // You can do whatever you want with this file.
15 ///////////////////////////////////////////////////////////////////////////////
17 #include "tests.h"
19 // liblzma internal header file needed for:
20 // UNPADDED_SIZE_MIN
21 // UNPADDED_SIZE_MAX
22 // vli_ceil4
23 #include "common/index.h"
26 #define MEMLIMIT (UINT64_C(1) << 20)
28 static uint8_t *decode_buffer;
29 static size_t decode_buffer_size = 0;
30 static lzma_index *decode_test_index;
33 static void
34 test_lzma_index_memusage(void)
36 // The return value from lzma_index_memusage is an approximation
37 // of the amount of memory needed for lzma_index for a given
38 // amount of Streams and Blocks. It will be an upperbound,
39 // so this test will mostly sanity check and error check the
40 // function.
42 // The maximum number of Streams should be UINT32_MAX in the
43 // current implementation even though the parameter is lzma_vli.
44 assert_uint_eq(lzma_index_memusage((lzma_vli)UINT32_MAX + 1, 1),
45 UINT64_MAX);
47 // The maximum number of Blocks should be LZMA_VLI_MAX
48 assert_uint_eq(lzma_index_memusage(1, LZMA_VLI_MAX), UINT64_MAX);
50 // Number of Streams must be non-zero
51 assert_uint_eq(lzma_index_memusage(0, 1), UINT64_MAX);
53 // Number of Blocks CAN be zero
54 assert_uint(lzma_index_memusage(1, 0), !=, UINT64_MAX);
56 // Arbitrary values for Stream and Block should work without error
57 // and should always increase
58 uint64_t previous = 1;
59 lzma_vli streams = 1;
60 lzma_vli blocks = 1;
62 // Test 100 different increasing values for Streams and Block
63 for (int i = 0; i < 100; i++) {
64 uint64_t current = lzma_index_memusage(streams, blocks);
65 assert_uint(current, >, previous);
66 previous = current;
67 streams += 29;
68 blocks += 107;
71 // Force integer overflow in calculation (should result in an error)
72 assert_uint_eq(lzma_index_memusage(UINT32_MAX, LZMA_VLI_MAX),
73 UINT64_MAX);
77 static void
78 test_lzma_index_memused(void)
80 // Very similar to test_lzma_index_memusage above since
81 // lzma_index_memused is essentially a wrapper for
82 // lzma_index_memusage
83 lzma_index *idx = lzma_index_init(NULL);
84 assert_true(idx != NULL);
86 // Test with empty Index
87 assert_uint(lzma_index_memused(idx), <, UINT64_MAX);
89 // Append small Blocks and then test again (should pass).
90 for (lzma_vli i = 0; i < 10; i++)
91 assert_lzma_ret(lzma_index_append(idx, NULL,
92 UNPADDED_SIZE_MIN, 1), LZMA_OK);
94 assert_uint(lzma_index_memused(idx), <, UINT64_MAX);
96 lzma_index_end(idx, NULL);
100 static void
101 test_lzma_index_append(void)
103 // Basic input-ouput test done here.
104 // Less trivial tests for this function are done throughout
105 // other tests.
107 // First test with NULL lzma_index
108 assert_lzma_ret(lzma_index_append(NULL, NULL, UNPADDED_SIZE_MIN,
109 1), LZMA_PROG_ERROR);
111 lzma_index *idx = lzma_index_init(NULL);
112 assert_true(idx != NULL);
114 // Test with invalid Unpadded Size
115 assert_lzma_ret(lzma_index_append(idx, NULL,
116 UNPADDED_SIZE_MIN - 1, 1), LZMA_PROG_ERROR);
117 assert_lzma_ret(lzma_index_append(idx, NULL,
118 UNPADDED_SIZE_MAX + 1, 1), LZMA_PROG_ERROR);
120 // Test with invalid Uncompressed Size
121 assert_lzma_ret(lzma_index_append(idx, NULL,
122 UNPADDED_SIZE_MAX, LZMA_VLI_MAX + 1),
123 LZMA_PROG_ERROR);
125 // Test expected successful Block appends
126 assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MIN,
127 1), LZMA_OK);
128 assert_lzma_ret(lzma_index_append(idx, NULL,
129 UNPADDED_SIZE_MIN * 2,
130 2), LZMA_OK);
131 assert_lzma_ret(lzma_index_append(idx, NULL,
132 UNPADDED_SIZE_MIN * 3,
133 3), LZMA_OK);
135 lzma_index_end(idx, NULL);
137 // Test uncompressed .xz file size growing too large.
138 // Should result in LZMA_DATA_ERROR.
139 idx = lzma_index_init(NULL);
141 assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MAX,
142 1), LZMA_DATA_ERROR);
144 // Test compressed size growing too large.
145 // Should result in LZMA_DATA_ERROR.
146 assert_lzma_ret(lzma_index_append(idx, NULL,
147 UNPADDED_SIZE_MIN, LZMA_VLI_MAX), LZMA_OK);
148 assert_lzma_ret(lzma_index_append(idx, NULL,
149 UNPADDED_SIZE_MIN, 1), LZMA_DATA_ERROR);
151 // Currently not testing for error case when the size of the Index
152 // grows too large to be stored. This was not practical to test for
153 // since too many Blocks needed to be created to cause this.
155 lzma_index_end(idx, NULL);
159 static void
160 test_lzma_index_stream_flags(void)
162 // Only trivial tests done here testing for basic functionality.
163 // More in-depth testing for this function will be done in
164 // test_lzma_index_checks.
166 // Testing for NULL inputs
167 assert_lzma_ret(lzma_index_stream_flags(NULL, NULL),
168 LZMA_PROG_ERROR);
170 lzma_index *idx = lzma_index_init(NULL);
171 assert_true(idx != NULL);
173 assert_lzma_ret(lzma_index_stream_flags(idx, NULL),
174 LZMA_PROG_ERROR);
176 lzma_stream_flags stream_flags = {
177 .version = 0,
178 .backward_size = LZMA_BACKWARD_SIZE_MIN,
179 .check = LZMA_CHECK_CRC32
182 assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
183 LZMA_OK);
185 lzma_index_end(idx, NULL);
189 static void
190 test_lzma_index_checks(void)
192 // Tests should still pass, even if some of the check types
193 // are disabled.
194 lzma_index *idx = lzma_index_init(NULL);
195 assert_true(idx != NULL);
197 lzma_stream_flags stream_flags = {
198 .version = 0,
199 .backward_size = LZMA_BACKWARD_SIZE_MIN,
200 .check = LZMA_CHECK_NONE
203 // First set the check type to None
204 assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
205 LZMA_OK);
206 assert_uint_eq(lzma_index_checks(idx),
207 UINT32_C(1) << LZMA_CHECK_NONE);
209 // Set the check type to CRC32 and repeat
210 stream_flags.check = LZMA_CHECK_CRC32;
211 assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
212 LZMA_OK);
213 assert_uint_eq(lzma_index_checks(idx),
214 UINT32_C(1) << LZMA_CHECK_CRC32);
216 // Set the check type to CRC64 and repeat
217 stream_flags.check = LZMA_CHECK_CRC64;
218 assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
219 LZMA_OK);
220 assert_uint_eq(lzma_index_checks(idx),
221 UINT32_C(1) << LZMA_CHECK_CRC64);
223 // Set the check type to SHA256 and repeat
224 stream_flags.check = LZMA_CHECK_SHA256;
225 assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
226 LZMA_OK);
227 assert_uint_eq(lzma_index_checks(idx),
228 UINT32_C(1) << LZMA_CHECK_SHA256);
230 // Create second lzma_index and cat to first
231 lzma_index *second = lzma_index_init(NULL);
232 assert_true(second != NULL);
234 // Set the check type to CRC32 for the second lzma_index
235 stream_flags.check = LZMA_CHECK_CRC32;
236 assert_lzma_ret(lzma_index_stream_flags(second, &stream_flags),
237 LZMA_OK);
239 assert_uint_eq(lzma_index_checks(second),
240 UINT32_C(1) << LZMA_CHECK_CRC32);
242 assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
244 // Index should now have both CRC32 and SHA256
245 assert_uint_eq(lzma_index_checks(idx),
246 (UINT32_C(1) << LZMA_CHECK_CRC32) |
247 (UINT32_C(1) << LZMA_CHECK_SHA256));
249 // Change the check type of the second Stream to SHA256
250 stream_flags.check = LZMA_CHECK_SHA256;
251 assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
252 LZMA_OK);
254 // Index should now have only SHA256
255 assert_uint_eq(lzma_index_checks(idx),
256 UINT32_C(1) << LZMA_CHECK_SHA256);
258 // Test with a third Stream
259 lzma_index *third = lzma_index_init(NULL);
260 assert_true(third != NULL);
262 stream_flags.check = LZMA_CHECK_CRC64;
263 assert_lzma_ret(lzma_index_stream_flags(third, &stream_flags),
264 LZMA_OK);
266 assert_uint_eq(lzma_index_checks(third),
267 UINT32_C(1) << LZMA_CHECK_CRC64);
269 assert_lzma_ret(lzma_index_cat(idx, third, NULL), LZMA_OK);
271 // Index should now have CRC64 and SHA256
272 assert_uint_eq(lzma_index_checks(idx),
273 (UINT32_C(1) << LZMA_CHECK_CRC64) |
274 (UINT32_C(1) << LZMA_CHECK_SHA256));
276 lzma_index_end(idx, NULL);
280 static void
281 test_lzma_index_stream_padding(void)
283 // Test NULL lzma_index
284 assert_lzma_ret(lzma_index_stream_padding(NULL, 0),
285 LZMA_PROG_ERROR);
287 lzma_index *idx = lzma_index_init(NULL);
288 assert_true(idx != NULL);
290 // Test Stream Padding not a multiple of 4
291 assert_lzma_ret(lzma_index_stream_padding(idx, 3),
292 LZMA_PROG_ERROR);
294 // Test Stream Padding too large
295 assert_lzma_ret(lzma_index_stream_padding(idx, LZMA_VLI_MAX - 3),
296 LZMA_DATA_ERROR);
298 // Test Stream Padding valid
299 assert_lzma_ret(lzma_index_stream_padding(idx, 0x1000),
300 LZMA_OK);
301 assert_lzma_ret(lzma_index_stream_padding(idx, 4),
302 LZMA_OK);
303 assert_lzma_ret(lzma_index_stream_padding(idx, 0),
304 LZMA_OK);
306 // Test Stream Padding causing the file size to grow too large
307 assert_lzma_ret(lzma_index_append(idx, NULL,
308 LZMA_VLI_MAX - 0x1000, 1), LZMA_OK);
309 assert_lzma_ret(lzma_index_stream_padding(idx, 0x1000),
310 LZMA_DATA_ERROR);
312 lzma_index_end(idx, NULL);
316 static void
317 test_lzma_index_stream_count(void)
319 lzma_index *idx = lzma_index_init(NULL);
320 assert_true(idx != NULL);
322 assert_uint_eq(lzma_index_stream_count(idx), 1);
324 // Appending Blocks should not change the Stream count value
325 assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MIN,
326 1), LZMA_OK);
328 assert_uint_eq(lzma_index_stream_count(idx), 1);
330 // Test with multiple Streams
331 for (uint32_t i = 0; i < 100; i++) {
332 lzma_index *idx_cat = lzma_index_init(NULL);
333 assert_true(idx != NULL);
334 assert_lzma_ret(lzma_index_cat(idx, idx_cat, NULL), LZMA_OK);
335 assert_uint_eq(lzma_index_stream_count(idx), i + 2);
338 lzma_index_end(idx, NULL);
342 static void
343 test_lzma_index_block_count(void)
345 lzma_index *idx = lzma_index_init(NULL);
346 assert_true(idx != NULL);
348 assert_uint_eq(lzma_index_block_count(idx), 0);
350 const uint32_t iterations = 0x1000;
351 for (uint32_t i = 0; i < iterations; i++) {
352 assert_lzma_ret(lzma_index_append(idx, NULL,
353 UNPADDED_SIZE_MIN, 1), LZMA_OK);
354 assert_uint_eq(lzma_index_block_count(idx), i + 1);
357 // Create new lzma_index with a few Blocks
358 lzma_index *second = lzma_index_init(NULL);
359 assert_true(second != NULL);
361 assert_lzma_ret(lzma_index_append(second, NULL,
362 UNPADDED_SIZE_MIN, 1), LZMA_OK);
363 assert_lzma_ret(lzma_index_append(second, NULL,
364 UNPADDED_SIZE_MIN, 1), LZMA_OK);
365 assert_lzma_ret(lzma_index_append(second, NULL,
366 UNPADDED_SIZE_MIN, 1), LZMA_OK);
368 assert_uint_eq(lzma_index_block_count(second), 3);
370 // Concatenate the lzma_indexes together and the result should have
371 // the sum of the two individual counts.
372 assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
373 assert_uint_eq(lzma_index_block_count(idx), iterations + 3);
375 assert_lzma_ret(lzma_index_append(idx, NULL,
376 UNPADDED_SIZE_MIN, 1), LZMA_OK);
378 assert_uint_eq(lzma_index_block_count(idx), iterations + 4);
380 lzma_index_end(idx, NULL);
384 static void
385 test_lzma_index_size(void)
387 lzma_index *idx = lzma_index_init(NULL);
388 assert_true(idx != NULL);
390 // Base size should be:
391 // 1 byte Index Indicator
392 // 1 byte Number of Records
393 // 0 bytes Records
394 // 2 bytes Index Padding
395 // 4 bytes CRC32
396 // Total: 8 bytes
397 assert_uint_eq(lzma_index_size(idx), 8);
399 assert_lzma_ret(lzma_index_append(idx, NULL,
400 UNPADDED_SIZE_MIN, 1), LZMA_OK);
402 // New size should be:
403 // 1 byte Index Indicator
404 // 1 byte Number of Records
405 // 2 bytes Records
406 // 0 bytes Index Padding
407 // 4 bytes CRC32
408 // Total: 8 bytes
409 assert_uint_eq(lzma_index_size(idx), 8);
411 assert_lzma_ret(lzma_index_append(idx, NULL,
412 LZMA_VLI_MAX / 4, LZMA_VLI_MAX / 4), LZMA_OK);
414 // New size should be:
415 // 1 byte Index Indicator
416 // 1 byte Number of Records
417 // 20 bytes Records
418 // 2 bytes Index Padding
419 // 4 bytes CRC32
420 // Total: 28 bytes
421 assert_uint_eq(lzma_index_size(idx), 28);
423 lzma_index_end(idx, NULL);
427 static void
428 test_lzma_index_stream_size(void)
430 lzma_index *idx = lzma_index_init(NULL);
431 assert_true(idx != NULL);
433 // Stream size calculated by:
434 // Size of Stream Header (12 bytes)
435 // Size of all Blocks
436 // Size of the Index
437 // Size of the Stream Footer (12 bytes)
439 // First test with empty Index
440 // Stream size should be:
441 // Size of Stream Header - 12 bytes
442 // Size of all Blocks - 0 bytes
443 // Size of Index - 8 bytes
444 // Size of Stream Footer - 12 bytes
445 // Total: 32 bytes
446 assert_uint_eq(lzma_index_stream_size(idx), 32);
448 // Next, append a few Blocks and retest
449 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
450 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
451 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
453 // Stream size should be:
454 // Size of Stream Header - 12 bytes
455 // Size of all Blocks - 3000 bytes
456 // Size of Index - 16 bytes
457 // Size of Stream Footer - 12 bytes
458 // Total: 3040 bytes
459 assert_uint_eq(lzma_index_stream_size(idx), 3040);
461 lzma_index *second = lzma_index_init(NULL);
462 assert_true(second != NULL);
464 assert_uint_eq(lzma_index_stream_size(second), 32);
465 assert_lzma_ret(lzma_index_append(second, NULL, 1000, 1), LZMA_OK);
467 // Stream size should be:
468 // Size of Stream Header - 12 bytes
469 // Size of all Blocks - 1000 bytes
470 // Size of Index - 12 bytes
471 // Size of Stream Footer - 12 bytes
472 // Total: 1036 bytes
473 assert_uint_eq(lzma_index_stream_size(second), 1036);
475 assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
477 // Stream size should be:
478 // Size of Stream Header - 12 bytes
479 // Size of all Blocks - 4000 bytes
480 // Size of Index - 20 bytes
481 // Size of Stream Footer - 12 bytes
482 // Total: 4044 bytes
483 assert_uint_eq(lzma_index_stream_size(idx), 4044);
485 lzma_index_end(idx, NULL);
489 static void
490 test_lzma_index_total_size(void)
492 lzma_index *idx = lzma_index_init(NULL);
493 assert_true(idx != NULL);
495 // First test empty lzma_index.
496 // Result should be 0 since no Blocks have been added.
497 assert_uint_eq(lzma_index_total_size(idx), 0);
499 // Add a few Blocks and retest after each append
500 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
501 assert_uint_eq(lzma_index_total_size(idx), 1000);
503 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
504 assert_uint_eq(lzma_index_total_size(idx), 2000);
506 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
507 assert_uint_eq(lzma_index_total_size(idx), 3000);
509 // Create second lzma_index and append Blocks to it.
510 lzma_index *second = lzma_index_init(NULL);
511 assert_true(second != NULL);
513 assert_uint_eq(lzma_index_total_size(second), 0);
515 assert_lzma_ret(lzma_index_append(second, NULL, 100, 1), LZMA_OK);
516 assert_uint_eq(lzma_index_total_size(second), 100);
518 assert_lzma_ret(lzma_index_append(second, NULL, 100, 1), LZMA_OK);
519 assert_uint_eq(lzma_index_total_size(second), 200);
521 // Concatenate the Streams together
522 assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
524 // The resulting total size should be the size of all Blocks
525 // from both Streams
526 assert_uint_eq(lzma_index_total_size(idx), 3200);
528 lzma_index_end(idx, NULL);
532 static void
533 test_lzma_index_file_size(void)
535 lzma_index *idx = lzma_index_init(NULL);
536 assert_true(idx != NULL);
538 // Should be the same as test_lzma_index_stream_size with
539 // only one Stream and no Stream Padding.
540 assert_uint_eq(lzma_index_file_size(idx), 32);
542 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
543 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
544 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
546 assert_uint_eq(lzma_index_file_size(idx), 3040);
548 // Next add Stream Padding
549 assert_lzma_ret(lzma_index_stream_padding(idx, 1000),
550 LZMA_OK);
552 assert_uint_eq(lzma_index_file_size(idx), 4040);
554 // Create second lzma_index.
555 // Very similar to test_lzma_index_stream_size, but
556 // the values should include the headers of the second Stream.
557 lzma_index *second = lzma_index_init(NULL);
558 assert_true(second != NULL);
560 assert_lzma_ret(lzma_index_append(second, NULL, 1000, 1), LZMA_OK);
561 assert_uint_eq(lzma_index_stream_size(second), 1036);
563 assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
565 // .xz file size should be:
566 // Size of 2 Stream Headers - 12 * 2 bytes
567 // Size of all Blocks - 3000 + 1000 bytes
568 // Size of 2 Indexes - 16 + 12 bytes
569 // Size of Stream Padding - 1000 bytes
570 // Size of 2 Stream Footers - 12 * 2 bytes
571 // Total: 5076 bytes
572 assert_uint_eq(lzma_index_file_size(idx), 5076);
574 lzma_index_end(idx, NULL);
578 static void
579 test_lzma_index_uncompressed_size(void)
581 lzma_index *idx = lzma_index_init(NULL);
582 assert_true(idx != NULL);
584 // Empty lzma_index should have 0 uncompressed .xz file size.
585 assert_uint_eq(lzma_index_uncompressed_size(idx), 0);
587 // Append a few small Blocks
588 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
589 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 10), LZMA_OK);
590 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 100), LZMA_OK);
592 assert_uint_eq(lzma_index_uncompressed_size(idx), 111);
594 // Create another lzma_index
595 lzma_index *second = lzma_index_init(NULL);
596 assert_true(second != NULL);
598 // Append a few small Blocks
599 assert_lzma_ret(lzma_index_append(second, NULL, 1000, 2), LZMA_OK);
600 assert_lzma_ret(lzma_index_append(second, NULL, 1000, 20), LZMA_OK);
601 assert_lzma_ret(lzma_index_append(second, NULL, 1000, 200), LZMA_OK);
603 assert_uint_eq(lzma_index_uncompressed_size(second), 222);
605 // Concatenate second lzma_index to first
606 assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
608 // New uncompressed .xz file size should be the sum of the two Streams
609 assert_uint_eq(lzma_index_uncompressed_size(idx), 333);
611 // Append one more Block to the lzma_index and ensure that
612 // it is properly updated
613 assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 111), LZMA_OK);
614 assert_uint_eq(lzma_index_uncompressed_size(idx), 444);
616 lzma_index_end(idx, NULL);
620 static void
621 test_lzma_index_iter_init(void)
623 // Testing basic init functionality.
624 // The init function should call rewind on the iterator.
625 lzma_index *first = lzma_index_init(NULL);
626 assert_true(first != NULL);
628 lzma_index *second = lzma_index_init(NULL);
629 assert_true(second != NULL);
631 lzma_index *third = lzma_index_init(NULL);
632 assert_true(third != NULL);
634 assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK);
635 assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK);
637 lzma_index_iter iter;
638 lzma_index_iter_init(&iter, first);
640 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
641 assert_uint_eq(iter.stream.number, 1);
642 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
643 assert_uint_eq(iter.stream.number, 2);
645 lzma_index_iter_init(&iter, first);
647 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
648 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
649 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
650 assert_uint_eq(iter.stream.number, 3);
654 static void
655 test_lzma_index_iter_rewind(void)
657 lzma_index *first = lzma_index_init(NULL);
658 assert_true(first != NULL);
660 lzma_index_iter iter;
661 lzma_index_iter_init(&iter, first);
663 // Append 3 Blocks and iterate over each. This is to test
664 // the LZMA_INDEX_ITER_BLOCK mode.
665 for (uint32_t i = 0; i < 3; i++) {
666 assert_lzma_ret(lzma_index_append(first, NULL,
667 UNPADDED_SIZE_MIN, 1), LZMA_OK);
668 assert_false(lzma_index_iter_next(&iter,
669 LZMA_INDEX_ITER_BLOCK));
670 assert_uint_eq(iter.block.number_in_file, i + 1);
673 // Rewind back to the begining and iterate over the Blocks again
674 lzma_index_iter_rewind(&iter);
676 // Should be able to re-iterate over the Blocks again.
677 for (uint32_t i = 0; i < 3; i++) {
678 assert_false(lzma_index_iter_next(&iter,
679 LZMA_INDEX_ITER_BLOCK));
680 assert_uint_eq(iter.block.number_in_file, i + 1);
683 // Next concatenate two more lzma_indexes, iterate over them,
684 // rewind, and iterate over them again. This is to test
685 // the LZMA_INDEX_ITER_STREAM mode.
686 lzma_index *second = lzma_index_init(NULL);
687 assert_true(second != NULL);
689 lzma_index *third = lzma_index_init(NULL);
690 assert_true(third != NULL);
692 assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK);
693 assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK);
695 assert_false(lzma_index_iter_next(&iter,
696 LZMA_INDEX_ITER_STREAM));
697 assert_false(lzma_index_iter_next(&iter,
698 LZMA_INDEX_ITER_STREAM));
700 assert_uint_eq(iter.stream.number, 3);
702 lzma_index_iter_rewind(&iter);
704 for (uint32_t i = 0; i < 3; i++) {
705 assert_false(lzma_index_iter_next(&iter,
706 LZMA_INDEX_ITER_STREAM));
707 assert_uint_eq(iter.stream.number, i + 1);
710 lzma_index_end(first, NULL);
714 static void
715 test_lzma_index_iter_next(void)
717 lzma_index *first = lzma_index_init(NULL);
718 assert_true(first != NULL);
720 lzma_index_iter iter;
721 lzma_index_iter_init(&iter, first);
723 // First test bad mode values
724 for (uint32_t i = LZMA_INDEX_ITER_NONEMPTY_BLOCK + 1; i < 100; i++)
725 assert_true(lzma_index_iter_next(&iter, i));
727 // Test iterating over Blocks
728 assert_lzma_ret(lzma_index_append(first, NULL,
729 UNPADDED_SIZE_MIN, 1), LZMA_OK);
730 assert_lzma_ret(lzma_index_append(first, NULL,
731 UNPADDED_SIZE_MIN * 2, 10), LZMA_OK);
732 assert_lzma_ret(lzma_index_append(first, NULL,
733 UNPADDED_SIZE_MIN * 3, 100), LZMA_OK);
735 // For Blocks, need to verify:
736 // - number_in_file (overall Block number)
737 // - compressed_file_offset
738 // - uncompressed_file_offset
739 // - number_in_stream (Block number relative to current Stream)
740 // - compressed_stream_offset
741 // - uncompressed_stream_offset
742 // - uncompressed_size
743 // - unpadded_size
744 // - total_size
746 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
748 // Verify Block data stored correctly
749 assert_uint_eq(iter.block.number_in_file, 1);
751 // Should start right after the Stream Header
752 assert_uint_eq(iter.block.compressed_file_offset,
753 LZMA_STREAM_HEADER_SIZE);
754 assert_uint_eq(iter.block.uncompressed_file_offset, 0);
755 assert_uint_eq(iter.block.number_in_stream, 1);
756 assert_uint_eq(iter.block.compressed_stream_offset,
757 LZMA_STREAM_HEADER_SIZE);
758 assert_uint_eq(iter.block.uncompressed_stream_offset, 0);
759 assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN);
760 assert_uint_eq(iter.block.total_size, vli_ceil4(UNPADDED_SIZE_MIN));
762 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
764 // Verify Block data stored correctly
765 assert_uint_eq(iter.block.number_in_file, 2);
766 assert_uint_eq(iter.block.compressed_file_offset,
767 LZMA_STREAM_HEADER_SIZE +
768 vli_ceil4(UNPADDED_SIZE_MIN));
769 assert_uint_eq(iter.block.uncompressed_file_offset, 1);
770 assert_uint_eq(iter.block.number_in_stream, 2);
771 assert_uint_eq(iter.block.compressed_stream_offset,
772 LZMA_STREAM_HEADER_SIZE +
773 vli_ceil4(UNPADDED_SIZE_MIN));
774 assert_uint_eq(iter.block.uncompressed_stream_offset, 1);
775 assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN * 2);
776 assert_uint_eq(iter.block.total_size, vli_ceil4(UNPADDED_SIZE_MIN * 2));
778 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
780 // Verify Block data stored correctly
781 assert_uint_eq(iter.block.number_in_file, 3);
782 assert_uint_eq(iter.block.compressed_file_offset,
783 LZMA_STREAM_HEADER_SIZE +
784 vli_ceil4(UNPADDED_SIZE_MIN) +
785 vli_ceil4(UNPADDED_SIZE_MIN * 2));
786 assert_uint_eq(iter.block.uncompressed_file_offset, 11);
787 assert_uint_eq(iter.block.number_in_stream, 3);
788 assert_uint_eq(iter.block.compressed_stream_offset,
789 LZMA_STREAM_HEADER_SIZE +
790 vli_ceil4(UNPADDED_SIZE_MIN) +
791 vli_ceil4(UNPADDED_SIZE_MIN * 2));
792 assert_uint_eq(iter.block.uncompressed_stream_offset, 11);
793 assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN * 3);
794 assert_uint_eq(iter.block.total_size,
795 vli_ceil4(UNPADDED_SIZE_MIN * 3));
797 // Only three Blocks were added, so this should return true
798 assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
800 const lzma_vli second_stream_compressed_start =
801 LZMA_STREAM_HEADER_SIZE * 2 +
802 vli_ceil4(UNPADDED_SIZE_MIN) +
803 vli_ceil4(UNPADDED_SIZE_MIN * 2) +
804 vli_ceil4(UNPADDED_SIZE_MIN * 3) +
805 lzma_index_size(first);
806 const lzma_vli second_stream_uncompressed_start = 1 + 10 + 100;
808 // Test iterating over Streams.
809 // The second Stream will have 0 Blocks
810 lzma_index *second = lzma_index_init(NULL);
811 assert_true(second != NULL);
813 // Set Stream Flags for Stream 2
814 lzma_stream_flags flags = {
815 .version = 0,
816 .backward_size = LZMA_BACKWARD_SIZE_MIN,
817 .check = LZMA_CHECK_CRC32
820 assert_lzma_ret(lzma_index_stream_flags(second, &flags), LZMA_OK);
822 // The Second stream will have 8 bytes of Stream Padding
823 assert_lzma_ret(lzma_index_stream_padding(second, 8), LZMA_OK);
825 const lzma_vli second_stream_index_size = lzma_index_size(second);
827 // The third Stream will have 2 Blocks
828 lzma_index *third = lzma_index_init(NULL);
829 assert_true(third != NULL);
831 assert_lzma_ret(lzma_index_append(third, NULL, 32, 20), LZMA_OK);
832 assert_lzma_ret(lzma_index_append(third, NULL, 64, 40), LZMA_OK);
834 const lzma_vli third_stream_index_size = lzma_index_size(third);
836 assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK);
837 assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK);
839 // For Streams, need to verify:
840 // - flags (Stream Flags)
841 // - number (Stream count)
842 // - block_count
843 // - compressed_offset
844 // - uncompressed_offset
845 // - compressed_size
846 // - uncompressed_size
847 // - padding (Stream Padding)
848 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
850 // Verify Stream
851 assert_uint_eq(iter.stream.flags->backward_size,
852 LZMA_BACKWARD_SIZE_MIN);
853 assert_uint_eq(iter.stream.flags->check, LZMA_CHECK_CRC32);
854 assert_uint_eq(iter.stream.number, 2);
855 assert_uint_eq(iter.stream.block_count, 0);
856 assert_uint_eq(iter.stream.compressed_offset,
857 second_stream_compressed_start);
858 assert_uint_eq(iter.stream.uncompressed_offset,
859 second_stream_uncompressed_start);
860 assert_uint_eq(iter.stream.compressed_size,
861 LZMA_STREAM_HEADER_SIZE * 2 +
862 second_stream_index_size);
863 assert_uint_eq(iter.stream.uncompressed_size, 0);
864 assert_uint_eq(iter.stream.padding, 8);
866 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
868 // Verify Stream
869 const lzma_vli third_stream_compressed_start =
870 second_stream_compressed_start +
871 LZMA_STREAM_HEADER_SIZE * 2 +
872 8 + // Stream padding
873 second_stream_index_size;
874 const lzma_vli third_stream_uncompressed_start =
875 second_stream_uncompressed_start;
877 assert_uint_eq(iter.stream.number, 3);
878 assert_uint_eq(iter.stream.block_count, 2);
879 assert_uint_eq(iter.stream.compressed_offset,
880 third_stream_compressed_start);
881 assert_uint_eq(iter.stream.uncompressed_offset,
882 third_stream_uncompressed_start);
883 assert_uint_eq(iter.stream.compressed_size,
884 LZMA_STREAM_HEADER_SIZE * 2 +
885 96 + // Total compressed size
886 third_stream_index_size);
887 assert_uint_eq(iter.stream.uncompressed_size, 60);
888 assert_uint_eq(iter.stream.padding, 0);
890 assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM));
892 // Even after a failing call to next with ITER_STREAM mode,
893 // should still be able to iterate over the 2 Blocks in
894 // Stream 3.
895 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
897 // Verify both Blocks
899 // Next call to iterate Block should return true because the
900 // first Block can already be read from the LZMA_INDEX_ITER_STREAM
901 // call.
902 assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
904 // Rewind to test LZMA_INDEX_ITER_ANY
905 lzma_index_iter_rewind(&iter);
907 // Iterate past the first three Blocks
908 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
909 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
910 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
912 // Iterate past the next Stream
913 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
915 // Iterate past the next Stream
916 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
917 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
919 // Last call should fail
920 assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
922 // Rewind to test LZMA_INDEX_ITER_NONEMPTY_BLOCK
923 lzma_index_iter_rewind(&iter);
925 // Iterate past the first three Blocks
926 assert_false(lzma_index_iter_next(&iter,
927 LZMA_INDEX_ITER_NONEMPTY_BLOCK));
928 assert_false(lzma_index_iter_next(&iter,
929 LZMA_INDEX_ITER_NONEMPTY_BLOCK));
930 assert_false(lzma_index_iter_next(&iter,
931 LZMA_INDEX_ITER_NONEMPTY_BLOCK));
933 // Skip past the next Stream which has no Blocks.
934 // We will get to the first Block of the third Stream.
935 assert_false(lzma_index_iter_next(&iter,
936 LZMA_INDEX_ITER_NONEMPTY_BLOCK));
938 // Iterate past the second (the last) Block in the third Stream
939 assert_false(lzma_index_iter_next(&iter,
940 LZMA_INDEX_ITER_NONEMPTY_BLOCK));
942 // Last call should fail since there is nothing left to iterate over.
943 assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY));
945 lzma_index_end(first, NULL);
949 static void
950 test_lzma_index_iter_locate(void)
952 lzma_index *idx = lzma_index_init(NULL);
953 assert_true(idx != NULL);
955 lzma_index_iter iter;
956 lzma_index_iter_init(&iter, idx);
958 // Cannot locate anything from an empty Index.
959 assert_true(lzma_index_iter_locate(&iter, 0));
960 assert_true(lzma_index_iter_locate(&iter, 555));
962 // One empty Record: nothing is found since there's no uncompressed
963 // data.
964 assert_lzma_ret(lzma_index_append(idx, NULL, 16, 0), LZMA_OK);
965 assert_true(lzma_index_iter_locate(&iter, 0));
967 // Non-empty Record and we can find something.
968 assert_lzma_ret(lzma_index_append(idx, NULL, 32, 5), LZMA_OK);
969 assert_false(lzma_index_iter_locate(&iter, 0));
970 assert_uint_eq(iter.block.total_size, 32);
971 assert_uint_eq(iter.block.uncompressed_size, 5);
972 assert_uint_eq(iter.block.compressed_file_offset,
973 LZMA_STREAM_HEADER_SIZE + 16);
974 assert_uint_eq(iter.block.uncompressed_file_offset, 0);
976 // Still cannot find anything past the end.
977 assert_true(lzma_index_iter_locate(&iter, 5));
979 // Add the third Record.
980 assert_lzma_ret(lzma_index_append(idx, NULL, 40, 11), LZMA_OK);
982 assert_false(lzma_index_iter_locate(&iter, 0));
983 assert_uint_eq(iter.block.total_size, 32);
984 assert_uint_eq(iter.block.uncompressed_size, 5);
985 assert_uint_eq(iter.block.compressed_file_offset,
986 LZMA_STREAM_HEADER_SIZE + 16);
987 assert_uint_eq(iter.block.uncompressed_file_offset, 0);
989 assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
990 assert_uint_eq(iter.block.total_size, 40);
991 assert_uint_eq(iter.block.uncompressed_size, 11);
992 assert_uint_eq(iter.block.compressed_file_offset,
993 LZMA_STREAM_HEADER_SIZE + 16 + 32);
994 assert_uint_eq(iter.block.uncompressed_file_offset, 5);
996 assert_false(lzma_index_iter_locate(&iter, 2));
997 assert_uint_eq(iter.block.total_size, 32);
998 assert_uint_eq(iter.block.uncompressed_size, 5);
999 assert_uint_eq(iter.block.compressed_file_offset,
1000 LZMA_STREAM_HEADER_SIZE + 16);
1001 assert_uint_eq(iter.block.uncompressed_file_offset, 0);
1003 assert_false(lzma_index_iter_locate(&iter, 5));
1004 assert_uint_eq(iter.block.total_size, 40);
1005 assert_uint_eq(iter.block.uncompressed_size, 11);
1006 assert_uint_eq(iter.block.compressed_file_offset,
1007 LZMA_STREAM_HEADER_SIZE + 16 + 32);
1008 assert_uint_eq(iter.block.uncompressed_file_offset, 5);
1010 assert_false(lzma_index_iter_locate(&iter, 5 + 11 - 1));
1011 assert_uint_eq(iter.block.total_size, 40);
1012 assert_uint_eq(iter.block.uncompressed_size, 11);
1013 assert_uint_eq(iter.block.compressed_file_offset,
1014 LZMA_STREAM_HEADER_SIZE + 16 + 32);
1015 assert_uint_eq(iter.block.uncompressed_file_offset, 5);
1017 assert_true(lzma_index_iter_locate(&iter, 5 + 11));
1018 assert_true(lzma_index_iter_locate(&iter, 5 + 15));
1020 // Large Index
1021 lzma_index_end(idx, NULL);
1022 idx = lzma_index_init(NULL);
1023 assert_true(idx != NULL);
1024 lzma_index_iter_init(&iter, idx);
1026 for (uint32_t n = 4; n <= 4 * 5555; n += 4)
1027 assert_lzma_ret(lzma_index_append(idx, NULL, n + 8, n),
1028 LZMA_OK);
1030 assert_uint_eq(lzma_index_block_count(idx), 5555);
1032 // First Record
1033 assert_false(lzma_index_iter_locate(&iter, 0));
1034 assert_uint_eq(iter.block.total_size, 4 + 8);
1035 assert_uint_eq(iter.block.uncompressed_size, 4);
1036 assert_uint_eq(iter.block.compressed_file_offset,
1037 LZMA_STREAM_HEADER_SIZE);
1038 assert_uint_eq(iter.block.uncompressed_file_offset, 0);
1040 assert_false(lzma_index_iter_locate(&iter, 3));
1041 assert_uint_eq(iter.block.total_size, 4 + 8);
1042 assert_uint_eq(iter.block.uncompressed_size, 4);
1043 assert_uint_eq(iter.block.compressed_file_offset,
1044 LZMA_STREAM_HEADER_SIZE);
1045 assert_uint_eq(iter.block.uncompressed_file_offset, 0);
1047 // Second Record
1048 assert_false(lzma_index_iter_locate(&iter, 4));
1049 assert_uint_eq(iter.block.total_size, 2 * 4 + 8);
1050 assert_uint_eq(iter.block.uncompressed_size, 2 * 4);
1051 assert_uint_eq(iter.block.compressed_file_offset,
1052 LZMA_STREAM_HEADER_SIZE + 4 + 8);
1053 assert_uint_eq(iter.block.uncompressed_file_offset, 4);
1055 // Last Record
1056 assert_false(lzma_index_iter_locate(
1057 &iter, lzma_index_uncompressed_size(idx) - 1));
1058 assert_uint_eq(iter.block.total_size, 4 * 5555 + 8);
1059 assert_uint_eq(iter.block.uncompressed_size, 4 * 5555);
1060 assert_uint_eq(iter.block.compressed_file_offset,
1061 lzma_index_total_size(idx)
1062 + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
1063 assert_uint_eq(iter.block.uncompressed_file_offset,
1064 lzma_index_uncompressed_size(idx) - 4 * 5555);
1066 // Allocation chunk boundaries. See INDEX_GROUP_SIZE in
1067 // liblzma/common/index.c.
1068 const uint32_t group_multiple = 256 * 4;
1069 const uint32_t radius = 8;
1070 const uint32_t start = group_multiple - radius;
1071 lzma_vli ubase = 0;
1072 lzma_vli tbase = 0;
1073 uint32_t n;
1074 for (n = 1; n < start; ++n) {
1075 ubase += n * 4;
1076 tbase += n * 4 + 8;
1079 while (n < start + 2 * radius) {
1080 assert_false(lzma_index_iter_locate(&iter, ubase + n * 4));
1082 assert_uint_eq(iter.block.compressed_file_offset,
1083 tbase + n * 4 + 8
1084 + LZMA_STREAM_HEADER_SIZE);
1085 assert_uint_eq(iter.block.uncompressed_file_offset,
1086 ubase + n * 4);
1088 tbase += n * 4 + 8;
1089 ubase += n * 4;
1090 ++n;
1092 assert_uint_eq(iter.block.total_size, n * 4 + 8);
1093 assert_uint_eq(iter.block.uncompressed_size, n * 4);
1096 // Do it also backwards.
1097 while (n > start) {
1098 assert_false(lzma_index_iter_locate(
1099 &iter, ubase + (n - 1) * 4));
1101 assert_uint_eq(iter.block.total_size, n * 4 + 8);
1102 assert_uint_eq(iter.block.uncompressed_size, n * 4);
1104 --n;
1105 tbase -= n * 4 + 8;
1106 ubase -= n * 4;
1108 assert_uint_eq(iter.block.compressed_file_offset,
1109 tbase + n * 4 + 8
1110 + LZMA_STREAM_HEADER_SIZE);
1111 assert_uint_eq(iter.block.uncompressed_file_offset,
1112 ubase + n * 4);
1115 // Test locating in concatenated Index.
1116 lzma_index_end(idx, NULL);
1117 idx = lzma_index_init(NULL);
1118 assert_true(idx != NULL);
1119 lzma_index_iter_init(&iter, idx);
1120 for (n = 0; n < group_multiple; ++n)
1121 assert_lzma_ret(lzma_index_append(idx, NULL, 8, 0),
1122 LZMA_OK);
1123 assert_lzma_ret(lzma_index_append(idx, NULL, 16, 1), LZMA_OK);
1124 assert_false(lzma_index_iter_locate(&iter, 0));
1125 assert_uint_eq(iter.block.total_size, 16);
1126 assert_uint_eq(iter.block.uncompressed_size, 1);
1127 assert_uint_eq(iter.block.compressed_file_offset,
1128 LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
1129 assert_uint_eq(iter.block.uncompressed_file_offset, 0);
1131 lzma_index_end(idx, NULL);
1135 static void
1136 test_lzma_index_cat(void)
1138 // Most complex tests for this function are done in other tests.
1139 // This will mostly test basic functionality.
1141 lzma_index *dest = lzma_index_init(NULL);
1142 assert_true(dest != NULL);
1144 lzma_index *src = lzma_index_init(NULL);
1145 assert_true(src != NULL);
1147 // First test NULL dest or src
1148 assert_lzma_ret(lzma_index_cat(NULL, NULL, NULL), LZMA_PROG_ERROR);
1149 assert_lzma_ret(lzma_index_cat(dest, NULL, NULL), LZMA_PROG_ERROR);
1150 assert_lzma_ret(lzma_index_cat(NULL, src, NULL), LZMA_PROG_ERROR);
1152 // Check for uncompressed size overflow
1153 assert_lzma_ret(lzma_index_append(dest, NULL,
1154 (UNPADDED_SIZE_MAX / 2) + 1, 1), LZMA_OK);
1155 assert_lzma_ret(lzma_index_append(src, NULL,
1156 (UNPADDED_SIZE_MAX / 2) + 1, 1), LZMA_OK);
1157 assert_lzma_ret(lzma_index_cat(dest, src, NULL), LZMA_DATA_ERROR);
1159 // Check for compressed size overflow
1160 dest = lzma_index_init(NULL);
1161 assert_true(dest != NULL);
1163 src = lzma_index_init(NULL);
1164 assert_true(src != NULL);
1166 assert_lzma_ret(lzma_index_append(dest, NULL,
1167 UNPADDED_SIZE_MIN, LZMA_VLI_MAX - 1), LZMA_OK);
1168 assert_lzma_ret(lzma_index_append(src, NULL,
1169 UNPADDED_SIZE_MIN, LZMA_VLI_MAX - 1), LZMA_OK);
1170 assert_lzma_ret(lzma_index_cat(dest, src, NULL), LZMA_DATA_ERROR);
1172 lzma_index_end(dest, NULL);
1173 lzma_index_end(src, NULL);
1177 // Helper function for test_lzma_index_dup().
1178 static bool
1179 index_is_equal(const lzma_index *a, const lzma_index *b)
1181 // Compare only the Stream and Block sizes and offsets.
1182 lzma_index_iter ra, rb;
1183 lzma_index_iter_init(&ra, a);
1184 lzma_index_iter_init(&rb, b);
1186 while (true) {
1187 bool reta = lzma_index_iter_next(&ra, LZMA_INDEX_ITER_ANY);
1188 bool retb = lzma_index_iter_next(&rb, LZMA_INDEX_ITER_ANY);
1190 // If both iterators finish at the same time, then the Indexes
1191 // are identical.
1192 if (reta)
1193 return retb;
1195 if (ra.stream.number != rb.stream.number
1196 || ra.stream.block_count
1197 != rb.stream.block_count
1198 || ra.stream.compressed_offset
1199 != rb.stream.compressed_offset
1200 || ra.stream.uncompressed_offset
1201 != rb.stream.uncompressed_offset
1202 || ra.stream.compressed_size
1203 != rb.stream.compressed_size
1204 || ra.stream.uncompressed_size
1205 != rb.stream.uncompressed_size
1206 || ra.stream.padding
1207 != rb.stream.padding)
1208 return false;
1210 if (ra.stream.block_count == 0)
1211 continue;
1213 if (ra.block.number_in_file != rb.block.number_in_file
1214 || ra.block.compressed_file_offset
1215 != rb.block.compressed_file_offset
1216 || ra.block.uncompressed_file_offset
1217 != rb.block.uncompressed_file_offset
1218 || ra.block.number_in_stream
1219 != rb.block.number_in_stream
1220 || ra.block.compressed_stream_offset
1221 != rb.block.compressed_stream_offset
1222 || ra.block.uncompressed_stream_offset
1223 != rb.block.uncompressed_stream_offset
1224 || ra.block.uncompressed_size
1225 != rb.block.uncompressed_size
1226 || ra.block.unpadded_size
1227 != rb.block.unpadded_size
1228 || ra.block.total_size
1229 != rb.block.total_size)
1230 return false;
1235 // Allocator that succeeds for the first two allocation but fails the rest.
1236 static void *
1237 my_alloc(void *opaque, size_t a, size_t b)
1239 (void)opaque;
1241 static unsigned count = 0;
1242 if (++count > 2)
1243 return NULL;
1245 return malloc(a * b);
1248 static const lzma_allocator test_index_dup_alloc = { &my_alloc, NULL, NULL };
1251 static void
1252 test_lzma_index_dup(void)
1254 lzma_index *idx = lzma_index_init(NULL);
1255 assert_true(idx != NULL);
1257 // Test for the bug fix 21515d79d778b8730a434f151b07202d52a04611:
1258 // liblzma: Fix lzma_index_dup() for empty Streams.
1259 assert_lzma_ret(lzma_index_stream_padding(idx, 4), LZMA_OK);
1260 lzma_index *copy = lzma_index_dup(idx, NULL);
1261 assert_true(copy != NULL);
1262 assert_true(index_is_equal(idx, copy));
1263 lzma_index_end(copy, NULL);
1265 // Test for the bug fix 3bf857edfef51374f6f3fffae3d817f57d3264a0:
1266 // liblzma: Fix a memory leak in error path of lzma_index_dup().
1267 // Use Valgrind to see that there are no leaks.
1268 assert_lzma_ret(lzma_index_append(idx, NULL,
1269 UNPADDED_SIZE_MIN, 10), LZMA_OK);
1270 assert_lzma_ret(lzma_index_append(idx, NULL,
1271 UNPADDED_SIZE_MIN * 2, 100), LZMA_OK);
1272 assert_lzma_ret(lzma_index_append(idx, NULL,
1273 UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK);
1275 assert_true(lzma_index_dup(idx, &test_index_dup_alloc) == NULL);
1277 // Test a few streams and blocks
1278 lzma_index *second = lzma_index_init(NULL);
1279 assert_true(second != NULL);
1281 assert_lzma_ret(lzma_index_stream_padding(second, 16), LZMA_OK);
1283 lzma_index *third = lzma_index_init(NULL);
1284 assert_true(third != NULL);
1286 assert_lzma_ret(lzma_index_append(third, NULL,
1287 UNPADDED_SIZE_MIN * 10, 40), LZMA_OK);
1288 assert_lzma_ret(lzma_index_append(third, NULL,
1289 UNPADDED_SIZE_MIN * 20, 400), LZMA_OK);
1290 assert_lzma_ret(lzma_index_append(third, NULL,
1291 UNPADDED_SIZE_MIN * 30, 4000), LZMA_OK);
1293 assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
1294 assert_lzma_ret(lzma_index_cat(idx, third, NULL), LZMA_OK);
1296 copy = lzma_index_dup(idx, NULL);
1297 assert_true(copy != NULL);
1298 assert_true(index_is_equal(idx, copy));
1300 lzma_index_end(idx, NULL);
1303 #if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
1304 static void
1305 verify_index_buffer(const lzma_index *idx, const uint8_t *buffer,
1306 const size_t buffer_size)
1308 lzma_index_iter iter;
1309 lzma_index_iter_init(&iter, idx);
1311 size_t buffer_pos = 0;
1313 // Verify Index Indicator
1314 assert_uint_eq(buffer[buffer_pos++], 0);
1316 // Get Number of Records
1317 lzma_vli number_of_records = 0;
1318 lzma_vli block_count = 0;
1319 assert_lzma_ret(lzma_vli_decode(&number_of_records, NULL, buffer,
1320 &buffer_pos, buffer_size), LZMA_OK);
1322 while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)) {
1323 // Verify each Record (Unpadded Size, then Uncompressed Size).
1324 // Verify Unpadded Size.
1325 lzma_vli unpadded_size, uncompressed_size;
1326 assert_lzma_ret(lzma_vli_decode(&unpadded_size,
1327 NULL, buffer, &buffer_pos,
1328 buffer_size), LZMA_OK);
1329 assert_uint_eq(unpadded_size,
1330 iter.block.unpadded_size);
1332 // Verify Uncompressed Size
1333 assert_lzma_ret(lzma_vli_decode(&uncompressed_size,
1334 NULL, buffer, &buffer_pos,
1335 buffer_size), LZMA_OK);
1336 assert_uint_eq(uncompressed_size,
1337 iter.block.uncompressed_size);
1339 block_count++;
1342 // Verify Number of Records
1343 assert_uint_eq(number_of_records, block_count);
1345 // Verify Index Padding
1346 for (; buffer_pos % 4 != 0; buffer_pos++)
1347 assert_uint_eq(buffer[buffer_pos], 0);
1349 // Verify CRC32
1350 uint32_t crc32 = lzma_crc32(buffer, buffer_pos, 0);
1351 assert_uint_eq(read32le(buffer + buffer_pos), crc32);
1355 // In a few places the Index size is needed as a size_t but lzma_index_size()
1356 // returns lzma_vli.
1357 static size_t
1358 get_index_size(const lzma_index *idx)
1360 const lzma_vli size = lzma_index_size(idx);
1361 assert_uint(size, <, SIZE_MAX);
1362 return (size_t)size;
1364 #endif
1367 static void
1368 test_lzma_index_encoder(void)
1370 #if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
1371 assert_skip("Encoder or decoder support disabled");
1372 #else
1373 lzma_index *idx = lzma_index_init(NULL);
1374 assert_true(idx != NULL);
1376 lzma_stream strm = LZMA_STREAM_INIT;
1378 // First do basic NULL checks
1379 assert_lzma_ret(lzma_index_encoder(NULL, NULL), LZMA_PROG_ERROR);
1380 assert_lzma_ret(lzma_index_encoder(&strm, NULL), LZMA_PROG_ERROR);
1381 assert_lzma_ret(lzma_index_encoder(NULL, idx), LZMA_PROG_ERROR);
1383 // Append three small Blocks
1384 assert_lzma_ret(lzma_index_append(idx, NULL,
1385 UNPADDED_SIZE_MIN, 10), LZMA_OK);
1386 assert_lzma_ret(lzma_index_append(idx, NULL,
1387 UNPADDED_SIZE_MIN * 2, 100), LZMA_OK);
1388 assert_lzma_ret(lzma_index_append(idx, NULL,
1389 UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK);
1391 // Encode this lzma_index into a buffer
1392 size_t buffer_size = get_index_size(idx);
1393 uint8_t *buffer = tuktest_malloc(buffer_size);
1395 assert_lzma_ret(lzma_index_encoder(&strm, idx), LZMA_OK);
1397 strm.avail_out = buffer_size;
1398 strm.next_out = buffer;
1400 assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
1401 assert_uint_eq(strm.avail_out, 0);
1403 lzma_end(&strm);
1405 verify_index_buffer(idx, buffer, buffer_size);
1407 // Test with multiple Streams concatenated into 1 Index
1408 lzma_index *second = lzma_index_init(NULL);
1409 assert_true(second != NULL);
1411 // Include 1 Block
1412 assert_lzma_ret(lzma_index_append(second, NULL,
1413 UNPADDED_SIZE_MIN * 4, 20), LZMA_OK);
1415 // Include Stream Padding
1416 assert_lzma_ret(lzma_index_stream_padding(second, 16), LZMA_OK);
1418 assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
1419 buffer_size = get_index_size(idx);
1420 buffer = tuktest_malloc(buffer_size);
1421 assert_lzma_ret(lzma_index_encoder(&strm, idx), LZMA_OK);
1423 strm.avail_out = buffer_size;
1424 strm.next_out = buffer;
1426 assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
1427 assert_uint_eq(strm.avail_out, 0);
1429 verify_index_buffer(idx, buffer, buffer_size);
1431 lzma_end(&strm);
1432 #endif
1435 static void
1436 generate_index_decode_buffer(void)
1438 #ifdef HAVE_ENCODERS
1439 decode_test_index = lzma_index_init(NULL);
1440 if (decode_test_index == NULL)
1441 return;
1443 // Add 4 Blocks
1444 for (uint32_t i = 1; i < 5; i++)
1445 if (lzma_index_append(decode_test_index, NULL,
1446 0x1000 * i, 0x100 * i) != LZMA_OK)
1447 return;
1449 size_t size = lzma_index_size(decode_test_index);
1450 decode_buffer = tuktest_malloc(size);
1452 if (lzma_index_buffer_encode(decode_test_index,
1453 decode_buffer, &decode_buffer_size, size) != LZMA_OK)
1454 decode_buffer_size = 0;
1455 #endif
1459 #ifdef HAVE_DECODERS
1460 static void
1461 decode_index(const uint8_t *buffer, const size_t size, lzma_stream *strm,
1462 lzma_ret expected_error)
1464 strm->avail_in = size;
1465 strm->next_in = buffer;
1466 assert_lzma_ret(lzma_code(strm, LZMA_FINISH), expected_error);
1468 #endif
1471 static void
1472 test_lzma_index_decoder(void)
1474 #ifndef HAVE_DECODERS
1475 assert_skip("Decoder support disabled");
1476 #else
1477 if (decode_buffer_size == 0)
1478 assert_skip("Could not initialize decode test buffer");
1480 lzma_stream strm = LZMA_STREAM_INIT;
1482 assert_lzma_ret(lzma_index_decoder(NULL, NULL, MEMLIMIT),
1483 LZMA_PROG_ERROR);
1484 assert_lzma_ret(lzma_index_decoder(&strm, NULL, MEMLIMIT),
1485 LZMA_PROG_ERROR);
1486 assert_lzma_ret(lzma_index_decoder(NULL, &decode_test_index,
1487 MEMLIMIT), LZMA_PROG_ERROR);
1489 // Do actual decode
1490 lzma_index *idx;
1491 assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
1492 LZMA_OK);
1494 decode_index(decode_buffer, decode_buffer_size, &strm,
1495 LZMA_STREAM_END);
1497 // Compare results with expected
1498 assert_true(index_is_equal(decode_test_index, idx));
1500 lzma_index_end(idx, NULL);
1502 // Test again with too low memory limit
1503 assert_lzma_ret(lzma_index_decoder(&strm, &idx, 0), LZMA_OK);
1505 decode_index(decode_buffer, decode_buffer_size, &strm,
1506 LZMA_MEMLIMIT_ERROR);
1508 uint8_t *corrupt_buffer = tuktest_malloc(decode_buffer_size);
1509 memcpy(corrupt_buffer, decode_buffer, decode_buffer_size);
1511 assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
1512 LZMA_OK);
1514 // First corrupt the Index Indicator
1515 corrupt_buffer[0] ^= 1;
1516 decode_index(corrupt_buffer, decode_buffer_size, &strm,
1517 LZMA_DATA_ERROR);
1518 corrupt_buffer[0] ^= 1;
1520 // Corrupt something in the middle of Index
1521 corrupt_buffer[decode_buffer_size / 2] ^= 1;
1522 assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
1523 LZMA_OK);
1524 decode_index(corrupt_buffer, decode_buffer_size, &strm,
1525 LZMA_DATA_ERROR);
1526 corrupt_buffer[decode_buffer_size / 2] ^= 1;
1528 // Corrupt CRC32
1529 corrupt_buffer[decode_buffer_size - 1] ^= 1;
1530 assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
1531 LZMA_OK);
1532 decode_index(corrupt_buffer, decode_buffer_size, &strm,
1533 LZMA_DATA_ERROR);
1534 corrupt_buffer[decode_buffer_size - 1] ^= 1;
1536 // Corrupt Index Padding by setting it to non-zero
1537 corrupt_buffer[decode_buffer_size - 5] ^= 1;
1538 assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
1539 LZMA_OK);
1540 decode_index(corrupt_buffer, decode_buffer_size, &strm,
1541 LZMA_DATA_ERROR);
1542 corrupt_buffer[decode_buffer_size - 1] ^= 1;
1544 lzma_end(&strm);
1545 #endif
1549 static void
1550 test_lzma_index_buffer_encode(void)
1552 #if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
1553 assert_skip("Encoder or decoder support disabled");
1554 #else
1555 // More simple test than test_lzma_index_encoder() because
1556 // currently lzma_index_buffer_encode() is mostly a wrapper
1557 // around lzma_index_encoder() anyway.
1558 lzma_index *idx = lzma_index_init(NULL);
1559 assert_true(idx != NULL);
1561 assert_lzma_ret(lzma_index_append(idx, NULL,
1562 UNPADDED_SIZE_MIN, 10), LZMA_OK);
1563 assert_lzma_ret(lzma_index_append(idx, NULL,
1564 UNPADDED_SIZE_MIN * 2, 100), LZMA_OK);
1565 assert_lzma_ret(lzma_index_append(idx, NULL,
1566 UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK);
1568 size_t buffer_size = get_index_size(idx);
1569 uint8_t *buffer = tuktest_malloc(buffer_size);
1570 size_t out_pos = 1;
1572 // First test bad arguments
1573 assert_lzma_ret(lzma_index_buffer_encode(NULL, NULL, NULL, 0),
1574 LZMA_PROG_ERROR);
1575 assert_lzma_ret(lzma_index_buffer_encode(idx, NULL, NULL, 0),
1576 LZMA_PROG_ERROR);
1577 assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, NULL, 0),
1578 LZMA_PROG_ERROR);
1579 assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos,
1580 0), LZMA_PROG_ERROR);
1581 out_pos = 0;
1582 assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos,
1583 1), LZMA_BUF_ERROR);
1585 // Do encoding
1586 assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos,
1587 buffer_size), LZMA_OK);
1588 assert_uint_eq(out_pos, buffer_size);
1590 // Validate results
1591 verify_index_buffer(idx, buffer, buffer_size);
1592 #endif
1596 static void
1597 test_lzma_index_buffer_decode(void)
1599 #ifndef HAVE_DECODERS
1600 assert_skip("Decoder support disabled");
1601 #else
1602 if (decode_buffer_size == 0)
1603 assert_skip("Could not initialize decode test buffer");
1605 // Simple test since test_lzma_index_decoder() covers most of the
1606 // lzma_index_buffer_decode() code anyway.
1608 // First test NULL checks
1609 assert_lzma_ret(lzma_index_buffer_decode(NULL, NULL, NULL, NULL,
1610 NULL, 0), LZMA_PROG_ERROR);
1612 lzma_index *idx;
1613 uint64_t memlimit = MEMLIMIT;
1614 size_t in_pos = 0;
1616 assert_lzma_ret(lzma_index_buffer_decode(&idx, NULL, NULL, NULL,
1617 NULL, 0), LZMA_PROG_ERROR);
1619 assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
1620 NULL, NULL, 0), LZMA_PROG_ERROR);
1622 assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
1623 decode_buffer, NULL, 0), LZMA_PROG_ERROR);
1625 assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
1626 decode_buffer, NULL, 0), LZMA_PROG_ERROR);
1628 assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
1629 decode_buffer, &in_pos, 0), LZMA_DATA_ERROR);
1631 in_pos = 1;
1632 assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
1633 decode_buffer, &in_pos, 0), LZMA_PROG_ERROR);
1634 in_pos = 0;
1636 // Test expected successful decode
1637 assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
1638 decode_buffer, &in_pos, decode_buffer_size), LZMA_OK);
1640 assert_true(index_is_equal(decode_test_index, idx));
1642 // Test too small memlimit
1643 in_pos = 0;
1644 memlimit = 1;
1645 assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
1646 decode_buffer, &in_pos, decode_buffer_size),
1647 LZMA_MEMLIMIT_ERROR);
1648 assert_uint(memlimit, >, 1);
1649 assert_uint(memlimit, <, MEMLIMIT);
1650 #endif
1654 extern int
1655 main(int argc, char **argv)
1657 tuktest_start(argc, argv);
1658 generate_index_decode_buffer();
1659 tuktest_run(test_lzma_index_memusage);
1660 tuktest_run(test_lzma_index_memused);
1661 tuktest_run(test_lzma_index_append);
1662 tuktest_run(test_lzma_index_stream_flags);
1663 tuktest_run(test_lzma_index_checks);
1664 tuktest_run(test_lzma_index_stream_padding);
1665 tuktest_run(test_lzma_index_stream_count);
1666 tuktest_run(test_lzma_index_block_count);
1667 tuktest_run(test_lzma_index_size);
1668 tuktest_run(test_lzma_index_stream_size);
1669 tuktest_run(test_lzma_index_total_size);
1670 tuktest_run(test_lzma_index_file_size);
1671 tuktest_run(test_lzma_index_uncompressed_size);
1672 tuktest_run(test_lzma_index_iter_init);
1673 tuktest_run(test_lzma_index_iter_rewind);
1674 tuktest_run(test_lzma_index_iter_next);
1675 tuktest_run(test_lzma_index_iter_locate);
1676 tuktest_run(test_lzma_index_cat);
1677 tuktest_run(test_lzma_index_dup);
1678 tuktest_run(test_lzma_index_encoder);
1679 tuktest_run(test_lzma_index_decoder);
1680 tuktest_run(test_lzma_index_buffer_encode);
1681 tuktest_run(test_lzma_index_buffer_decode);
1682 lzma_index_end(decode_test_index, NULL);
1683 return tuktest_end();