1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Tests functions handling the lzma_index structure
6 /// \todo Implement tests for lzma_file_info_decoder
12 // This file has been put into the public domain.
13 // You can do whatever you want with this file.
15 ///////////////////////////////////////////////////////////////////////////////
19 // liblzma internal header file needed for:
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
;
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
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),
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;
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
);
71 // Force integer overflow in calculation (should result in an error)
72 assert_uint_eq(lzma_index_memusage(UINT32_MAX
, LZMA_VLI_MAX
),
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
);
101 test_lzma_index_append(void)
103 // Basic input-ouput test done here.
104 // Less trivial tests for this function are done throughout
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),
125 // Test expected successful Block appends
126 assert_lzma_ret(lzma_index_append(idx
, NULL
, UNPADDED_SIZE_MIN
,
128 assert_lzma_ret(lzma_index_append(idx
, NULL
,
129 UNPADDED_SIZE_MIN
* 2,
131 assert_lzma_ret(lzma_index_append(idx
, NULL
,
132 UNPADDED_SIZE_MIN
* 3,
135 lzma_index_end(idx
, NULL
);
137 // Test compressed .xz file size growing too large. This also tests
138 // a failing assert fixed in ae5c07b22a6b3766b84f409f1b6b5c100469068a.
139 // Should result in LZMA_DATA_ERROR.
140 idx
= lzma_index_init(NULL
);
142 // The calculation for maximum unpadded size is to make room for the
143 // second stream when lzma_index_cat() is called. The
144 // 4 * LZMA_STREAM_HEADER_SIZE is for the header and footer of
145 // both streams. The extra 24 bytes are for the size of the indexes
146 // for both streams. This allows us to maximize the unpadded sum
147 // during the lzma_index_append() call after the indexes have been
149 assert_lzma_ret(lzma_index_append(idx
, NULL
, UNPADDED_SIZE_MAX
150 - ((4 * LZMA_STREAM_HEADER_SIZE
) + 24), 1), LZMA_OK
);
152 lzma_index
*second
= lzma_index_init(NULL
);
153 assert_true(second
!= NULL
);
155 assert_lzma_ret(lzma_index_cat(second
, idx
, NULL
), LZMA_OK
);
157 assert_lzma_ret(lzma_index_append(second
, NULL
, UNPADDED_SIZE_MAX
, 1),
160 lzma_index_end(second
, NULL
);
162 // Test uncompressed size growing too large.
163 // Should result in LZMA_DATA_ERROR.
164 idx
= lzma_index_init(NULL
);
166 assert_lzma_ret(lzma_index_append(idx
, NULL
,
167 UNPADDED_SIZE_MIN
, LZMA_VLI_MAX
), LZMA_OK
);
168 assert_lzma_ret(lzma_index_append(idx
, NULL
,
169 UNPADDED_SIZE_MIN
, 1), LZMA_DATA_ERROR
);
171 lzma_index_end(idx
, NULL
);
173 // Currently not testing for error case when the size of the Index
174 // grows too large to be stored. This was not practical to test for
175 // since too many Blocks needed to be created to cause this.
180 test_lzma_index_stream_flags(void)
182 // Only trivial tests done here testing for basic functionality.
183 // More in-depth testing for this function will be done in
184 // test_lzma_index_checks.
186 // Testing for NULL inputs
187 assert_lzma_ret(lzma_index_stream_flags(NULL
, NULL
),
190 lzma_index
*idx
= lzma_index_init(NULL
);
191 assert_true(idx
!= NULL
);
193 assert_lzma_ret(lzma_index_stream_flags(idx
, NULL
),
196 lzma_stream_flags stream_flags
= {
198 .backward_size
= LZMA_BACKWARD_SIZE_MIN
,
199 .check
= LZMA_CHECK_CRC32
202 assert_lzma_ret(lzma_index_stream_flags(idx
, &stream_flags
),
205 lzma_index_end(idx
, NULL
);
210 test_lzma_index_checks(void)
212 // Tests should still pass, even if some of the check types
214 lzma_index
*idx
= lzma_index_init(NULL
);
215 assert_true(idx
!= NULL
);
217 lzma_stream_flags stream_flags
= {
219 .backward_size
= LZMA_BACKWARD_SIZE_MIN
,
220 .check
= LZMA_CHECK_NONE
223 // First set the check type to None
224 assert_lzma_ret(lzma_index_stream_flags(idx
, &stream_flags
),
226 assert_uint_eq(lzma_index_checks(idx
),
227 LZMA_INDEX_CHECK_MASK_NONE
);
229 // Set the check type to CRC32 and repeat
230 stream_flags
.check
= LZMA_CHECK_CRC32
;
231 assert_lzma_ret(lzma_index_stream_flags(idx
, &stream_flags
),
233 assert_uint_eq(lzma_index_checks(idx
),
234 LZMA_INDEX_CHECK_MASK_CRC32
);
236 // Set the check type to CRC64 and repeat
237 stream_flags
.check
= LZMA_CHECK_CRC64
;
238 assert_lzma_ret(lzma_index_stream_flags(idx
, &stream_flags
),
240 assert_uint_eq(lzma_index_checks(idx
),
241 LZMA_INDEX_CHECK_MASK_CRC64
);
243 // Set the check type to SHA256 and repeat
244 stream_flags
.check
= LZMA_CHECK_SHA256
;
245 assert_lzma_ret(lzma_index_stream_flags(idx
, &stream_flags
),
247 assert_uint_eq(lzma_index_checks(idx
),
248 LZMA_INDEX_CHECK_MASK_SHA256
);
250 // Create second lzma_index and cat to first
251 lzma_index
*second
= lzma_index_init(NULL
);
252 assert_true(second
!= NULL
);
254 // Set the check type to CRC32 for the second lzma_index
255 stream_flags
.check
= LZMA_CHECK_CRC32
;
256 assert_lzma_ret(lzma_index_stream_flags(second
, &stream_flags
),
259 assert_uint_eq(lzma_index_checks(second
),
260 LZMA_INDEX_CHECK_MASK_CRC32
);
262 assert_lzma_ret(lzma_index_cat(idx
, second
, NULL
), LZMA_OK
);
264 // Index should now have both CRC32 and SHA256
265 assert_uint_eq(lzma_index_checks(idx
),
266 LZMA_INDEX_CHECK_MASK_CRC32
|
267 LZMA_INDEX_CHECK_MASK_SHA256
);
269 // Change the check type of the second Stream to SHA256
270 stream_flags
.check
= LZMA_CHECK_SHA256
;
271 assert_lzma_ret(lzma_index_stream_flags(idx
, &stream_flags
),
274 // Index should now have only SHA256
275 assert_uint_eq(lzma_index_checks(idx
),
276 LZMA_INDEX_CHECK_MASK_SHA256
);
278 // Test with a third Stream
279 lzma_index
*third
= lzma_index_init(NULL
);
280 assert_true(third
!= NULL
);
282 stream_flags
.check
= LZMA_CHECK_CRC64
;
283 assert_lzma_ret(lzma_index_stream_flags(third
, &stream_flags
),
286 assert_uint_eq(lzma_index_checks(third
),
287 LZMA_INDEX_CHECK_MASK_CRC64
);
289 assert_lzma_ret(lzma_index_cat(idx
, third
, NULL
), LZMA_OK
);
291 // Index should now have CRC64 and SHA256
292 assert_uint_eq(lzma_index_checks(idx
),
293 LZMA_INDEX_CHECK_MASK_CRC64
|
294 LZMA_INDEX_CHECK_MASK_SHA256
);
296 lzma_index_end(idx
, NULL
);
301 test_lzma_index_stream_padding(void)
303 // Test NULL lzma_index
304 assert_lzma_ret(lzma_index_stream_padding(NULL
, 0),
307 lzma_index
*idx
= lzma_index_init(NULL
);
308 assert_true(idx
!= NULL
);
310 // Test Stream Padding not a multiple of 4
311 assert_lzma_ret(lzma_index_stream_padding(idx
, 3),
314 // Test Stream Padding too large
315 assert_lzma_ret(lzma_index_stream_padding(idx
, LZMA_VLI_MAX
- 3),
318 // Test Stream Padding valid
319 assert_lzma_ret(lzma_index_stream_padding(idx
, 0x1000),
321 assert_lzma_ret(lzma_index_stream_padding(idx
, 4),
323 assert_lzma_ret(lzma_index_stream_padding(idx
, 0),
326 // Test Stream Padding causing the file size to grow too large
327 assert_lzma_ret(lzma_index_append(idx
, NULL
,
328 LZMA_VLI_MAX
- 0x1000, 1), LZMA_OK
);
329 assert_lzma_ret(lzma_index_stream_padding(idx
, 0x1000),
332 lzma_index_end(idx
, NULL
);
337 test_lzma_index_stream_count(void)
339 lzma_index
*idx
= lzma_index_init(NULL
);
340 assert_true(idx
!= NULL
);
342 assert_uint_eq(lzma_index_stream_count(idx
), 1);
344 // Appending Blocks should not change the Stream count value
345 assert_lzma_ret(lzma_index_append(idx
, NULL
, UNPADDED_SIZE_MIN
,
348 assert_uint_eq(lzma_index_stream_count(idx
), 1);
350 // Test with multiple Streams
351 for (uint32_t i
= 0; i
< 100; i
++) {
352 lzma_index
*idx_cat
= lzma_index_init(NULL
);
353 assert_true(idx
!= NULL
);
354 assert_lzma_ret(lzma_index_cat(idx
, idx_cat
, NULL
), LZMA_OK
);
355 assert_uint_eq(lzma_index_stream_count(idx
), i
+ 2);
358 lzma_index_end(idx
, NULL
);
363 test_lzma_index_block_count(void)
365 lzma_index
*idx
= lzma_index_init(NULL
);
366 assert_true(idx
!= NULL
);
368 assert_uint_eq(lzma_index_block_count(idx
), 0);
370 const uint32_t iterations
= 0x1000;
371 for (uint32_t i
= 0; i
< iterations
; i
++) {
372 assert_lzma_ret(lzma_index_append(idx
, NULL
,
373 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
374 assert_uint_eq(lzma_index_block_count(idx
), i
+ 1);
377 // Create new lzma_index with a few Blocks
378 lzma_index
*second
= lzma_index_init(NULL
);
379 assert_true(second
!= NULL
);
381 assert_lzma_ret(lzma_index_append(second
, NULL
,
382 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
383 assert_lzma_ret(lzma_index_append(second
, NULL
,
384 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
385 assert_lzma_ret(lzma_index_append(second
, NULL
,
386 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
388 assert_uint_eq(lzma_index_block_count(second
), 3);
390 // Concatenate the lzma_indexes together and the result should have
391 // the sum of the two individual counts.
392 assert_lzma_ret(lzma_index_cat(idx
, second
, NULL
), LZMA_OK
);
393 assert_uint_eq(lzma_index_block_count(idx
), iterations
+ 3);
395 assert_lzma_ret(lzma_index_append(idx
, NULL
,
396 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
398 assert_uint_eq(lzma_index_block_count(idx
), iterations
+ 4);
400 lzma_index_end(idx
, NULL
);
405 test_lzma_index_size(void)
407 lzma_index
*idx
= lzma_index_init(NULL
);
408 assert_true(idx
!= NULL
);
410 // Base size should be:
411 // 1 byte Index Indicator
412 // 1 byte Number of Records
414 // 2 bytes Index Padding
417 assert_uint_eq(lzma_index_size(idx
), 8);
419 assert_lzma_ret(lzma_index_append(idx
, NULL
,
420 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
422 // New size should be:
423 // 1 byte Index Indicator
424 // 1 byte Number of Records
426 // 0 bytes Index Padding
429 assert_uint_eq(lzma_index_size(idx
), 8);
431 assert_lzma_ret(lzma_index_append(idx
, NULL
,
432 LZMA_VLI_MAX
/ 4, LZMA_VLI_MAX
/ 4), LZMA_OK
);
434 // New size should be:
435 // 1 byte Index Indicator
436 // 1 byte Number of Records
438 // 2 bytes Index Padding
441 assert_uint_eq(lzma_index_size(idx
), 28);
443 lzma_index_end(idx
, NULL
);
448 test_lzma_index_stream_size(void)
450 lzma_index
*idx
= lzma_index_init(NULL
);
451 assert_true(idx
!= NULL
);
453 // Stream size calculated by:
454 // Size of Stream Header (12 bytes)
455 // Size of all Blocks
457 // Size of the Stream Footer (12 bytes)
459 // First test with empty Index
460 // Stream size should be:
461 // Size of Stream Header - 12 bytes
462 // Size of all Blocks - 0 bytes
463 // Size of Index - 8 bytes
464 // Size of Stream Footer - 12 bytes
466 assert_uint_eq(lzma_index_stream_size(idx
), 32);
468 // Next, append a few Blocks and retest
469 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
470 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
471 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
473 // Stream size should be:
474 // Size of Stream Header - 12 bytes
475 // Size of all Blocks - 3000 bytes
476 // Size of Index - 16 bytes
477 // Size of Stream Footer - 12 bytes
479 assert_uint_eq(lzma_index_stream_size(idx
), 3040);
481 lzma_index
*second
= lzma_index_init(NULL
);
482 assert_true(second
!= NULL
);
484 assert_uint_eq(lzma_index_stream_size(second
), 32);
485 assert_lzma_ret(lzma_index_append(second
, NULL
, 1000, 1), LZMA_OK
);
487 // Stream size should be:
488 // Size of Stream Header - 12 bytes
489 // Size of all Blocks - 1000 bytes
490 // Size of Index - 12 bytes
491 // Size of Stream Footer - 12 bytes
493 assert_uint_eq(lzma_index_stream_size(second
), 1036);
495 assert_lzma_ret(lzma_index_cat(idx
, second
, NULL
), LZMA_OK
);
497 // Stream size should be:
498 // Size of Stream Header - 12 bytes
499 // Size of all Blocks - 4000 bytes
500 // Size of Index - 20 bytes
501 // Size of Stream Footer - 12 bytes
503 assert_uint_eq(lzma_index_stream_size(idx
), 4044);
505 lzma_index_end(idx
, NULL
);
510 test_lzma_index_total_size(void)
512 lzma_index
*idx
= lzma_index_init(NULL
);
513 assert_true(idx
!= NULL
);
515 // First test empty lzma_index.
516 // Result should be 0 since no Blocks have been added.
517 assert_uint_eq(lzma_index_total_size(idx
), 0);
519 // Add a few Blocks and retest after each append
520 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
521 assert_uint_eq(lzma_index_total_size(idx
), 1000);
523 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
524 assert_uint_eq(lzma_index_total_size(idx
), 2000);
526 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
527 assert_uint_eq(lzma_index_total_size(idx
), 3000);
529 // Create second lzma_index and append Blocks to it.
530 lzma_index
*second
= lzma_index_init(NULL
);
531 assert_true(second
!= NULL
);
533 assert_uint_eq(lzma_index_total_size(second
), 0);
535 assert_lzma_ret(lzma_index_append(second
, NULL
, 100, 1), LZMA_OK
);
536 assert_uint_eq(lzma_index_total_size(second
), 100);
538 assert_lzma_ret(lzma_index_append(second
, NULL
, 100, 1), LZMA_OK
);
539 assert_uint_eq(lzma_index_total_size(second
), 200);
541 // Concatenate the Streams together
542 assert_lzma_ret(lzma_index_cat(idx
, second
, NULL
), LZMA_OK
);
544 // The resulting total size should be the size of all Blocks
546 assert_uint_eq(lzma_index_total_size(idx
), 3200);
548 lzma_index_end(idx
, NULL
);
553 test_lzma_index_file_size(void)
555 lzma_index
*idx
= lzma_index_init(NULL
);
556 assert_true(idx
!= NULL
);
558 // Should be the same as test_lzma_index_stream_size with
559 // only one Stream and no Stream Padding.
560 assert_uint_eq(lzma_index_file_size(idx
), 32);
562 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
563 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
564 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
566 assert_uint_eq(lzma_index_file_size(idx
), 3040);
568 // Next add Stream Padding
569 assert_lzma_ret(lzma_index_stream_padding(idx
, 1000),
572 assert_uint_eq(lzma_index_file_size(idx
), 4040);
574 // Create second lzma_index.
575 // Very similar to test_lzma_index_stream_size, but
576 // the values should include the headers of the second Stream.
577 lzma_index
*second
= lzma_index_init(NULL
);
578 assert_true(second
!= NULL
);
580 assert_lzma_ret(lzma_index_append(second
, NULL
, 1000, 1), LZMA_OK
);
581 assert_uint_eq(lzma_index_stream_size(second
), 1036);
583 assert_lzma_ret(lzma_index_cat(idx
, second
, NULL
), LZMA_OK
);
585 // .xz file size should be:
586 // Size of 2 Stream Headers - 12 * 2 bytes
587 // Size of all Blocks - 3000 + 1000 bytes
588 // Size of 2 Indexes - 16 + 12 bytes
589 // Size of Stream Padding - 1000 bytes
590 // Size of 2 Stream Footers - 12 * 2 bytes
592 assert_uint_eq(lzma_index_file_size(idx
), 5076);
594 lzma_index_end(idx
, NULL
);
599 test_lzma_index_uncompressed_size(void)
601 lzma_index
*idx
= lzma_index_init(NULL
);
602 assert_true(idx
!= NULL
);
604 // Empty lzma_index should have 0 uncompressed .xz file size.
605 assert_uint_eq(lzma_index_uncompressed_size(idx
), 0);
607 // Append a few small Blocks
608 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 1), LZMA_OK
);
609 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 10), LZMA_OK
);
610 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 100), LZMA_OK
);
612 assert_uint_eq(lzma_index_uncompressed_size(idx
), 111);
614 // Create another lzma_index
615 lzma_index
*second
= lzma_index_init(NULL
);
616 assert_true(second
!= NULL
);
618 // Append a few small Blocks
619 assert_lzma_ret(lzma_index_append(second
, NULL
, 1000, 2), LZMA_OK
);
620 assert_lzma_ret(lzma_index_append(second
, NULL
, 1000, 20), LZMA_OK
);
621 assert_lzma_ret(lzma_index_append(second
, NULL
, 1000, 200), LZMA_OK
);
623 assert_uint_eq(lzma_index_uncompressed_size(second
), 222);
625 // Concatenate second lzma_index to first
626 assert_lzma_ret(lzma_index_cat(idx
, second
, NULL
), LZMA_OK
);
628 // New uncompressed .xz file size should be the sum of the two Streams
629 assert_uint_eq(lzma_index_uncompressed_size(idx
), 333);
631 // Append one more Block to the lzma_index and ensure that
632 // it is properly updated
633 assert_lzma_ret(lzma_index_append(idx
, NULL
, 1000, 111), LZMA_OK
);
634 assert_uint_eq(lzma_index_uncompressed_size(idx
), 444);
636 lzma_index_end(idx
, NULL
);
641 test_lzma_index_iter_init(void)
643 // Testing basic init functionality.
644 // The init function should call rewind on the iterator.
645 lzma_index
*first
= lzma_index_init(NULL
);
646 assert_true(first
!= NULL
);
648 lzma_index
*second
= lzma_index_init(NULL
);
649 assert_true(second
!= NULL
);
651 lzma_index
*third
= lzma_index_init(NULL
);
652 assert_true(third
!= NULL
);
654 assert_lzma_ret(lzma_index_cat(first
, second
, NULL
), LZMA_OK
);
655 assert_lzma_ret(lzma_index_cat(first
, third
, NULL
), LZMA_OK
);
657 lzma_index_iter iter
;
658 lzma_index_iter_init(&iter
, first
);
660 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_STREAM
));
661 assert_uint_eq(iter
.stream
.number
, 1);
662 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_STREAM
));
663 assert_uint_eq(iter
.stream
.number
, 2);
665 lzma_index_iter_init(&iter
, first
);
667 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_STREAM
));
668 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_STREAM
));
669 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_STREAM
));
670 assert_uint_eq(iter
.stream
.number
, 3);
672 lzma_index_end(first
, NULL
);
677 test_lzma_index_iter_rewind(void)
679 lzma_index
*first
= lzma_index_init(NULL
);
680 assert_true(first
!= NULL
);
682 lzma_index_iter iter
;
683 lzma_index_iter_init(&iter
, first
);
685 // Append 3 Blocks and iterate over each. This is to test
686 // the LZMA_INDEX_ITER_BLOCK mode.
687 for (uint32_t i
= 0; i
< 3; i
++) {
688 assert_lzma_ret(lzma_index_append(first
, NULL
,
689 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
690 assert_false(lzma_index_iter_next(&iter
,
691 LZMA_INDEX_ITER_BLOCK
));
692 assert_uint_eq(iter
.block
.number_in_file
, i
+ 1);
695 // Rewind back to the beginning and iterate over the Blocks again
696 lzma_index_iter_rewind(&iter
);
698 // Should be able to re-iterate over the Blocks again.
699 for (uint32_t i
= 0; i
< 3; i
++) {
700 assert_false(lzma_index_iter_next(&iter
,
701 LZMA_INDEX_ITER_BLOCK
));
702 assert_uint_eq(iter
.block
.number_in_file
, i
+ 1);
705 // Next concatenate two more lzma_indexes, iterate over them,
706 // rewind, and iterate over them again. This is to test
707 // the LZMA_INDEX_ITER_STREAM mode.
708 lzma_index
*second
= lzma_index_init(NULL
);
709 assert_true(second
!= NULL
);
711 lzma_index
*third
= lzma_index_init(NULL
);
712 assert_true(third
!= NULL
);
714 assert_lzma_ret(lzma_index_cat(first
, second
, NULL
), LZMA_OK
);
715 assert_lzma_ret(lzma_index_cat(first
, third
, NULL
), LZMA_OK
);
717 assert_false(lzma_index_iter_next(&iter
,
718 LZMA_INDEX_ITER_STREAM
));
719 assert_false(lzma_index_iter_next(&iter
,
720 LZMA_INDEX_ITER_STREAM
));
722 assert_uint_eq(iter
.stream
.number
, 3);
724 lzma_index_iter_rewind(&iter
);
726 for (uint32_t i
= 0; i
< 3; i
++) {
727 assert_false(lzma_index_iter_next(&iter
,
728 LZMA_INDEX_ITER_STREAM
));
729 assert_uint_eq(iter
.stream
.number
, i
+ 1);
732 lzma_index_end(first
, NULL
);
737 test_lzma_index_iter_next(void)
739 lzma_index
*first
= lzma_index_init(NULL
);
740 assert_true(first
!= NULL
);
742 lzma_index_iter iter
;
743 lzma_index_iter_init(&iter
, first
);
745 // First test bad mode values
746 for (uint32_t i
= LZMA_INDEX_ITER_NONEMPTY_BLOCK
+ 1; i
< 100; i
++)
747 assert_true(lzma_index_iter_next(&iter
, i
));
749 // Test iterating over Blocks
750 assert_lzma_ret(lzma_index_append(first
, NULL
,
751 UNPADDED_SIZE_MIN
, 1), LZMA_OK
);
752 assert_lzma_ret(lzma_index_append(first
, NULL
,
753 UNPADDED_SIZE_MIN
* 2, 10), LZMA_OK
);
754 assert_lzma_ret(lzma_index_append(first
, NULL
,
755 UNPADDED_SIZE_MIN
* 3, 100), LZMA_OK
);
757 // For Blocks, need to verify:
758 // - number_in_file (overall Block number)
759 // - compressed_file_offset
760 // - uncompressed_file_offset
761 // - number_in_stream (Block number relative to current Stream)
762 // - compressed_stream_offset
763 // - uncompressed_stream_offset
764 // - uncompressed_size
768 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_BLOCK
));
770 // Verify Block data stored correctly
771 assert_uint_eq(iter
.block
.number_in_file
, 1);
773 // Should start right after the Stream Header
774 assert_uint_eq(iter
.block
.compressed_file_offset
,
775 LZMA_STREAM_HEADER_SIZE
);
776 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 0);
777 assert_uint_eq(iter
.block
.number_in_stream
, 1);
778 assert_uint_eq(iter
.block
.compressed_stream_offset
,
779 LZMA_STREAM_HEADER_SIZE
);
780 assert_uint_eq(iter
.block
.uncompressed_stream_offset
, 0);
781 assert_uint_eq(iter
.block
.unpadded_size
, UNPADDED_SIZE_MIN
);
782 assert_uint_eq(iter
.block
.total_size
, vli_ceil4(UNPADDED_SIZE_MIN
));
784 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_BLOCK
));
786 // Verify Block data stored correctly
787 assert_uint_eq(iter
.block
.number_in_file
, 2);
788 assert_uint_eq(iter
.block
.compressed_file_offset
,
789 LZMA_STREAM_HEADER_SIZE
+
790 vli_ceil4(UNPADDED_SIZE_MIN
));
791 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 1);
792 assert_uint_eq(iter
.block
.number_in_stream
, 2);
793 assert_uint_eq(iter
.block
.compressed_stream_offset
,
794 LZMA_STREAM_HEADER_SIZE
+
795 vli_ceil4(UNPADDED_SIZE_MIN
));
796 assert_uint_eq(iter
.block
.uncompressed_stream_offset
, 1);
797 assert_uint_eq(iter
.block
.unpadded_size
, UNPADDED_SIZE_MIN
* 2);
798 assert_uint_eq(iter
.block
.total_size
, vli_ceil4(UNPADDED_SIZE_MIN
* 2));
800 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_BLOCK
));
802 // Verify Block data stored correctly
803 assert_uint_eq(iter
.block
.number_in_file
, 3);
804 assert_uint_eq(iter
.block
.compressed_file_offset
,
805 LZMA_STREAM_HEADER_SIZE
+
806 vli_ceil4(UNPADDED_SIZE_MIN
) +
807 vli_ceil4(UNPADDED_SIZE_MIN
* 2));
808 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 11);
809 assert_uint_eq(iter
.block
.number_in_stream
, 3);
810 assert_uint_eq(iter
.block
.compressed_stream_offset
,
811 LZMA_STREAM_HEADER_SIZE
+
812 vli_ceil4(UNPADDED_SIZE_MIN
) +
813 vli_ceil4(UNPADDED_SIZE_MIN
* 2));
814 assert_uint_eq(iter
.block
.uncompressed_stream_offset
, 11);
815 assert_uint_eq(iter
.block
.unpadded_size
, UNPADDED_SIZE_MIN
* 3);
816 assert_uint_eq(iter
.block
.total_size
,
817 vli_ceil4(UNPADDED_SIZE_MIN
* 3));
819 // Only three Blocks were added, so this should return true
820 assert_true(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_BLOCK
));
822 const lzma_vli second_stream_compressed_start
=
823 LZMA_STREAM_HEADER_SIZE
* 2 +
824 vli_ceil4(UNPADDED_SIZE_MIN
) +
825 vli_ceil4(UNPADDED_SIZE_MIN
* 2) +
826 vli_ceil4(UNPADDED_SIZE_MIN
* 3) +
827 lzma_index_size(first
);
828 const lzma_vli second_stream_uncompressed_start
= 1 + 10 + 100;
830 // Test iterating over Streams.
831 // The second Stream will have 0 Blocks
832 lzma_index
*second
= lzma_index_init(NULL
);
833 assert_true(second
!= NULL
);
835 // Set Stream Flags for Stream 2
836 lzma_stream_flags flags
= {
838 .backward_size
= LZMA_BACKWARD_SIZE_MIN
,
839 .check
= LZMA_CHECK_CRC32
842 assert_lzma_ret(lzma_index_stream_flags(second
, &flags
), LZMA_OK
);
844 // The Second stream will have 8 bytes of Stream Padding
845 assert_lzma_ret(lzma_index_stream_padding(second
, 8), LZMA_OK
);
847 const lzma_vli second_stream_index_size
= lzma_index_size(second
);
849 // The third Stream will have 2 Blocks
850 lzma_index
*third
= lzma_index_init(NULL
);
851 assert_true(third
!= NULL
);
853 assert_lzma_ret(lzma_index_append(third
, NULL
, 32, 20), LZMA_OK
);
854 assert_lzma_ret(lzma_index_append(third
, NULL
, 64, 40), LZMA_OK
);
856 const lzma_vli third_stream_index_size
= lzma_index_size(third
);
858 assert_lzma_ret(lzma_index_cat(first
, second
, NULL
), LZMA_OK
);
859 assert_lzma_ret(lzma_index_cat(first
, third
, NULL
), LZMA_OK
);
861 // For Streams, need to verify:
862 // - flags (Stream Flags)
863 // - number (Stream count)
865 // - compressed_offset
866 // - uncompressed_offset
868 // - uncompressed_size
869 // - padding (Stream Padding)
870 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_STREAM
));
873 assert_uint_eq(iter
.stream
.flags
->backward_size
,
874 LZMA_BACKWARD_SIZE_MIN
);
875 assert_uint_eq(iter
.stream
.flags
->check
, LZMA_CHECK_CRC32
);
876 assert_uint_eq(iter
.stream
.number
, 2);
877 assert_uint_eq(iter
.stream
.block_count
, 0);
878 assert_uint_eq(iter
.stream
.compressed_offset
,
879 second_stream_compressed_start
);
880 assert_uint_eq(iter
.stream
.uncompressed_offset
,
881 second_stream_uncompressed_start
);
882 assert_uint_eq(iter
.stream
.compressed_size
,
883 LZMA_STREAM_HEADER_SIZE
* 2 +
884 second_stream_index_size
);
885 assert_uint_eq(iter
.stream
.uncompressed_size
, 0);
886 assert_uint_eq(iter
.stream
.padding
, 8);
888 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_STREAM
));
891 const lzma_vli third_stream_compressed_start
=
892 second_stream_compressed_start
+
893 LZMA_STREAM_HEADER_SIZE
* 2 +
894 8 + // Stream padding
895 second_stream_index_size
;
896 const lzma_vli third_stream_uncompressed_start
=
897 second_stream_uncompressed_start
;
899 assert_uint_eq(iter
.stream
.number
, 3);
900 assert_uint_eq(iter
.stream
.block_count
, 2);
901 assert_uint_eq(iter
.stream
.compressed_offset
,
902 third_stream_compressed_start
);
903 assert_uint_eq(iter
.stream
.uncompressed_offset
,
904 third_stream_uncompressed_start
);
905 assert_uint_eq(iter
.stream
.compressed_size
,
906 LZMA_STREAM_HEADER_SIZE
* 2 +
907 96 + // Total compressed size
908 third_stream_index_size
);
909 assert_uint_eq(iter
.stream
.uncompressed_size
, 60);
910 assert_uint_eq(iter
.stream
.padding
, 0);
912 assert_true(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_STREAM
));
914 // Even after a failing call to next with ITER_STREAM mode,
915 // should still be able to iterate over the 2 Blocks in
917 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_BLOCK
));
919 // Verify both Blocks
921 // Next call to iterate Block should return true because the
922 // first Block can already be read from the LZMA_INDEX_ITER_STREAM
924 assert_true(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_BLOCK
));
926 // Rewind to test LZMA_INDEX_ITER_ANY
927 lzma_index_iter_rewind(&iter
);
929 // Iterate past the first three Blocks
930 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
));
931 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
));
932 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
));
934 // Iterate past the next Stream
935 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
));
937 // Iterate past the next Stream
938 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
));
939 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
));
941 // Last call should fail
942 assert_true(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
));
944 // Rewind to test LZMA_INDEX_ITER_NONEMPTY_BLOCK
945 lzma_index_iter_rewind(&iter
);
947 // Iterate past the first three Blocks
948 assert_false(lzma_index_iter_next(&iter
,
949 LZMA_INDEX_ITER_NONEMPTY_BLOCK
));
950 assert_false(lzma_index_iter_next(&iter
,
951 LZMA_INDEX_ITER_NONEMPTY_BLOCK
));
952 assert_false(lzma_index_iter_next(&iter
,
953 LZMA_INDEX_ITER_NONEMPTY_BLOCK
));
955 // Skip past the next Stream which has no Blocks.
956 // We will get to the first Block of the third Stream.
957 assert_false(lzma_index_iter_next(&iter
,
958 LZMA_INDEX_ITER_NONEMPTY_BLOCK
));
960 // Iterate past the second (the last) Block in the third Stream
961 assert_false(lzma_index_iter_next(&iter
,
962 LZMA_INDEX_ITER_NONEMPTY_BLOCK
));
964 // Last call should fail since there is nothing left to iterate over.
965 assert_true(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
));
967 lzma_index_end(first
, NULL
);
972 test_lzma_index_iter_locate(void)
974 lzma_index
*idx
= lzma_index_init(NULL
);
975 assert_true(idx
!= NULL
);
977 lzma_index_iter iter
;
978 lzma_index_iter_init(&iter
, idx
);
980 // Cannot locate anything from an empty Index.
981 assert_true(lzma_index_iter_locate(&iter
, 0));
982 assert_true(lzma_index_iter_locate(&iter
, 555));
984 // One empty Record: nothing is found since there's no uncompressed
986 assert_lzma_ret(lzma_index_append(idx
, NULL
, 16, 0), LZMA_OK
);
987 assert_true(lzma_index_iter_locate(&iter
, 0));
989 // Non-empty Record and we can find something.
990 assert_lzma_ret(lzma_index_append(idx
, NULL
, 32, 5), LZMA_OK
);
991 assert_false(lzma_index_iter_locate(&iter
, 0));
992 assert_uint_eq(iter
.block
.total_size
, 32);
993 assert_uint_eq(iter
.block
.uncompressed_size
, 5);
994 assert_uint_eq(iter
.block
.compressed_file_offset
,
995 LZMA_STREAM_HEADER_SIZE
+ 16);
996 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 0);
998 // Still cannot find anything past the end.
999 assert_true(lzma_index_iter_locate(&iter
, 5));
1001 // Add the third Record.
1002 assert_lzma_ret(lzma_index_append(idx
, NULL
, 40, 11), LZMA_OK
);
1004 assert_false(lzma_index_iter_locate(&iter
, 0));
1005 assert_uint_eq(iter
.block
.total_size
, 32);
1006 assert_uint_eq(iter
.block
.uncompressed_size
, 5);
1007 assert_uint_eq(iter
.block
.compressed_file_offset
,
1008 LZMA_STREAM_HEADER_SIZE
+ 16);
1009 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 0);
1011 assert_false(lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_BLOCK
));
1012 assert_uint_eq(iter
.block
.total_size
, 40);
1013 assert_uint_eq(iter
.block
.uncompressed_size
, 11);
1014 assert_uint_eq(iter
.block
.compressed_file_offset
,
1015 LZMA_STREAM_HEADER_SIZE
+ 16 + 32);
1016 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 5);
1018 assert_false(lzma_index_iter_locate(&iter
, 2));
1019 assert_uint_eq(iter
.block
.total_size
, 32);
1020 assert_uint_eq(iter
.block
.uncompressed_size
, 5);
1021 assert_uint_eq(iter
.block
.compressed_file_offset
,
1022 LZMA_STREAM_HEADER_SIZE
+ 16);
1023 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 0);
1025 assert_false(lzma_index_iter_locate(&iter
, 5));
1026 assert_uint_eq(iter
.block
.total_size
, 40);
1027 assert_uint_eq(iter
.block
.uncompressed_size
, 11);
1028 assert_uint_eq(iter
.block
.compressed_file_offset
,
1029 LZMA_STREAM_HEADER_SIZE
+ 16 + 32);
1030 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 5);
1032 assert_false(lzma_index_iter_locate(&iter
, 5 + 11 - 1));
1033 assert_uint_eq(iter
.block
.total_size
, 40);
1034 assert_uint_eq(iter
.block
.uncompressed_size
, 11);
1035 assert_uint_eq(iter
.block
.compressed_file_offset
,
1036 LZMA_STREAM_HEADER_SIZE
+ 16 + 32);
1037 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 5);
1039 assert_true(lzma_index_iter_locate(&iter
, 5 + 11));
1040 assert_true(lzma_index_iter_locate(&iter
, 5 + 15));
1043 lzma_index_end(idx
, NULL
);
1044 idx
= lzma_index_init(NULL
);
1045 assert_true(idx
!= NULL
);
1046 lzma_index_iter_init(&iter
, idx
);
1048 for (uint32_t n
= 4; n
<= 4 * 5555; n
+= 4)
1049 assert_lzma_ret(lzma_index_append(idx
, NULL
, n
+ 8, n
),
1052 assert_uint_eq(lzma_index_block_count(idx
), 5555);
1055 assert_false(lzma_index_iter_locate(&iter
, 0));
1056 assert_uint_eq(iter
.block
.total_size
, 4 + 8);
1057 assert_uint_eq(iter
.block
.uncompressed_size
, 4);
1058 assert_uint_eq(iter
.block
.compressed_file_offset
,
1059 LZMA_STREAM_HEADER_SIZE
);
1060 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 0);
1062 assert_false(lzma_index_iter_locate(&iter
, 3));
1063 assert_uint_eq(iter
.block
.total_size
, 4 + 8);
1064 assert_uint_eq(iter
.block
.uncompressed_size
, 4);
1065 assert_uint_eq(iter
.block
.compressed_file_offset
,
1066 LZMA_STREAM_HEADER_SIZE
);
1067 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 0);
1070 assert_false(lzma_index_iter_locate(&iter
, 4));
1071 assert_uint_eq(iter
.block
.total_size
, 2 * 4 + 8);
1072 assert_uint_eq(iter
.block
.uncompressed_size
, 2 * 4);
1073 assert_uint_eq(iter
.block
.compressed_file_offset
,
1074 LZMA_STREAM_HEADER_SIZE
+ 4 + 8);
1075 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 4);
1078 assert_false(lzma_index_iter_locate(
1079 &iter
, lzma_index_uncompressed_size(idx
) - 1));
1080 assert_uint_eq(iter
.block
.total_size
, 4 * 5555 + 8);
1081 assert_uint_eq(iter
.block
.uncompressed_size
, 4 * 5555);
1082 assert_uint_eq(iter
.block
.compressed_file_offset
,
1083 lzma_index_total_size(idx
)
1084 + LZMA_STREAM_HEADER_SIZE
- 4 * 5555 - 8);
1085 assert_uint_eq(iter
.block
.uncompressed_file_offset
,
1086 lzma_index_uncompressed_size(idx
) - 4 * 5555);
1088 // Allocation chunk boundaries. See INDEX_GROUP_SIZE in
1089 // liblzma/common/index.c.
1090 const uint32_t group_multiple
= 256 * 4;
1091 const uint32_t radius
= 8;
1092 const uint32_t start
= group_multiple
- radius
;
1096 for (n
= 1; n
< start
; ++n
) {
1101 while (n
< start
+ 2 * radius
) {
1102 assert_false(lzma_index_iter_locate(&iter
, ubase
+ n
* 4));
1104 assert_uint_eq(iter
.block
.compressed_file_offset
,
1106 + LZMA_STREAM_HEADER_SIZE
);
1107 assert_uint_eq(iter
.block
.uncompressed_file_offset
,
1114 assert_uint_eq(iter
.block
.total_size
, n
* 4 + 8);
1115 assert_uint_eq(iter
.block
.uncompressed_size
, n
* 4);
1118 // Do it also backwards.
1120 assert_false(lzma_index_iter_locate(
1121 &iter
, ubase
+ (n
- 1) * 4));
1123 assert_uint_eq(iter
.block
.total_size
, n
* 4 + 8);
1124 assert_uint_eq(iter
.block
.uncompressed_size
, n
* 4);
1130 assert_uint_eq(iter
.block
.compressed_file_offset
,
1132 + LZMA_STREAM_HEADER_SIZE
);
1133 assert_uint_eq(iter
.block
.uncompressed_file_offset
,
1137 // Test locating in concatenated Index.
1138 lzma_index_end(idx
, NULL
);
1139 idx
= lzma_index_init(NULL
);
1140 assert_true(idx
!= NULL
);
1141 lzma_index_iter_init(&iter
, idx
);
1142 for (n
= 0; n
< group_multiple
; ++n
)
1143 assert_lzma_ret(lzma_index_append(idx
, NULL
, 8, 0),
1145 assert_lzma_ret(lzma_index_append(idx
, NULL
, 16, 1), LZMA_OK
);
1146 assert_false(lzma_index_iter_locate(&iter
, 0));
1147 assert_uint_eq(iter
.block
.total_size
, 16);
1148 assert_uint_eq(iter
.block
.uncompressed_size
, 1);
1149 assert_uint_eq(iter
.block
.compressed_file_offset
,
1150 LZMA_STREAM_HEADER_SIZE
+ group_multiple
* 8);
1151 assert_uint_eq(iter
.block
.uncompressed_file_offset
, 0);
1153 lzma_index_end(idx
, NULL
);
1158 test_lzma_index_cat(void)
1160 // Most complex tests for this function are done in other tests.
1161 // This will mostly test basic functionality.
1163 lzma_index
*dest
= lzma_index_init(NULL
);
1164 assert_true(dest
!= NULL
);
1166 lzma_index
*src
= lzma_index_init(NULL
);
1167 assert_true(src
!= NULL
);
1169 // First test NULL dest or src
1170 assert_lzma_ret(lzma_index_cat(NULL
, NULL
, NULL
), LZMA_PROG_ERROR
);
1171 assert_lzma_ret(lzma_index_cat(dest
, NULL
, NULL
), LZMA_PROG_ERROR
);
1172 assert_lzma_ret(lzma_index_cat(NULL
, src
, NULL
), LZMA_PROG_ERROR
);
1174 // Check for uncompressed size overflow
1175 assert_lzma_ret(lzma_index_append(dest
, NULL
,
1176 (UNPADDED_SIZE_MAX
/ 2) + 1, 1), LZMA_OK
);
1177 assert_lzma_ret(lzma_index_append(src
, NULL
,
1178 (UNPADDED_SIZE_MAX
/ 2) + 1, 1), LZMA_OK
);
1179 assert_lzma_ret(lzma_index_cat(dest
, src
, NULL
), LZMA_DATA_ERROR
);
1181 // Check for compressed size overflow
1182 lzma_index_end(src
, NULL
);
1183 lzma_index_end(dest
, NULL
);
1185 dest
= lzma_index_init(NULL
);
1186 assert_true(dest
!= NULL
);
1188 src
= lzma_index_init(NULL
);
1189 assert_true(src
!= NULL
);
1191 assert_lzma_ret(lzma_index_append(dest
, NULL
,
1192 UNPADDED_SIZE_MIN
, LZMA_VLI_MAX
- 1), LZMA_OK
);
1193 assert_lzma_ret(lzma_index_append(src
, NULL
,
1194 UNPADDED_SIZE_MIN
, LZMA_VLI_MAX
- 1), LZMA_OK
);
1195 assert_lzma_ret(lzma_index_cat(dest
, src
, NULL
), LZMA_DATA_ERROR
);
1197 lzma_index_end(dest
, NULL
);
1198 lzma_index_end(src
, NULL
);
1202 // Helper function for test_lzma_index_dup().
1204 index_is_equal(const lzma_index
*a
, const lzma_index
*b
)
1206 // Compare only the Stream and Block sizes and offsets.
1207 lzma_index_iter ra
, rb
;
1208 lzma_index_iter_init(&ra
, a
);
1209 lzma_index_iter_init(&rb
, b
);
1212 bool reta
= lzma_index_iter_next(&ra
, LZMA_INDEX_ITER_ANY
);
1213 bool retb
= lzma_index_iter_next(&rb
, LZMA_INDEX_ITER_ANY
);
1215 // If both iterators finish at the same time, then the Indexes
1220 if (ra
.stream
.number
!= rb
.stream
.number
1221 || ra
.stream
.block_count
1222 != rb
.stream
.block_count
1223 || ra
.stream
.compressed_offset
1224 != rb
.stream
.compressed_offset
1225 || ra
.stream
.uncompressed_offset
1226 != rb
.stream
.uncompressed_offset
1227 || ra
.stream
.compressed_size
1228 != rb
.stream
.compressed_size
1229 || ra
.stream
.uncompressed_size
1230 != rb
.stream
.uncompressed_size
1231 || ra
.stream
.padding
1232 != rb
.stream
.padding
)
1235 if (ra
.stream
.block_count
== 0)
1238 if (ra
.block
.number_in_file
!= rb
.block
.number_in_file
1239 || ra
.block
.compressed_file_offset
1240 != rb
.block
.compressed_file_offset
1241 || ra
.block
.uncompressed_file_offset
1242 != rb
.block
.uncompressed_file_offset
1243 || ra
.block
.number_in_stream
1244 != rb
.block
.number_in_stream
1245 || ra
.block
.compressed_stream_offset
1246 != rb
.block
.compressed_stream_offset
1247 || ra
.block
.uncompressed_stream_offset
1248 != rb
.block
.uncompressed_stream_offset
1249 || ra
.block
.uncompressed_size
1250 != rb
.block
.uncompressed_size
1251 || ra
.block
.unpadded_size
1252 != rb
.block
.unpadded_size
1253 || ra
.block
.total_size
1254 != rb
.block
.total_size
)
1260 // Allocator that succeeds for the first two allocation but fails the rest.
1262 my_alloc(void *opaque
, size_t a
, size_t b
)
1266 static unsigned count
= 0;
1270 return malloc(a
* b
);
1273 static const lzma_allocator test_index_dup_alloc
= { &my_alloc
, NULL
, NULL
};
1277 test_lzma_index_dup(void)
1279 lzma_index
*idx
= lzma_index_init(NULL
);
1280 assert_true(idx
!= NULL
);
1282 // Test for the bug fix 21515d79d778b8730a434f151b07202d52a04611:
1283 // liblzma: Fix lzma_index_dup() for empty Streams.
1284 assert_lzma_ret(lzma_index_stream_padding(idx
, 4), LZMA_OK
);
1285 lzma_index
*copy
= lzma_index_dup(idx
, NULL
);
1286 assert_true(copy
!= NULL
);
1287 assert_true(index_is_equal(idx
, copy
));
1288 lzma_index_end(copy
, NULL
);
1290 // Test for the bug fix 3bf857edfef51374f6f3fffae3d817f57d3264a0:
1291 // liblzma: Fix a memory leak in error path of lzma_index_dup().
1292 // Use Valgrind to see that there are no leaks.
1293 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1294 UNPADDED_SIZE_MIN
, 10), LZMA_OK
);
1295 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1296 UNPADDED_SIZE_MIN
* 2, 100), LZMA_OK
);
1297 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1298 UNPADDED_SIZE_MIN
* 3, 1000), LZMA_OK
);
1300 assert_true(lzma_index_dup(idx
, &test_index_dup_alloc
) == NULL
);
1302 // Test a few streams and blocks
1303 lzma_index
*second
= lzma_index_init(NULL
);
1304 assert_true(second
!= NULL
);
1306 assert_lzma_ret(lzma_index_stream_padding(second
, 16), LZMA_OK
);
1308 lzma_index
*third
= lzma_index_init(NULL
);
1309 assert_true(third
!= NULL
);
1311 assert_lzma_ret(lzma_index_append(third
, NULL
,
1312 UNPADDED_SIZE_MIN
* 10, 40), LZMA_OK
);
1313 assert_lzma_ret(lzma_index_append(third
, NULL
,
1314 UNPADDED_SIZE_MIN
* 20, 400), LZMA_OK
);
1315 assert_lzma_ret(lzma_index_append(third
, NULL
,
1316 UNPADDED_SIZE_MIN
* 30, 4000), LZMA_OK
);
1318 assert_lzma_ret(lzma_index_cat(idx
, second
, NULL
), LZMA_OK
);
1319 assert_lzma_ret(lzma_index_cat(idx
, third
, NULL
), LZMA_OK
);
1321 copy
= lzma_index_dup(idx
, NULL
);
1322 assert_true(copy
!= NULL
);
1323 assert_true(index_is_equal(idx
, copy
));
1325 lzma_index_end(copy
, NULL
);
1326 lzma_index_end(idx
, NULL
);
1329 #if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
1331 verify_index_buffer(const lzma_index
*idx
, const uint8_t *buffer
,
1332 const size_t buffer_size
)
1334 lzma_index_iter iter
;
1335 lzma_index_iter_init(&iter
, idx
);
1337 size_t buffer_pos
= 0;
1339 // Verify Index Indicator
1340 assert_uint_eq(buffer
[buffer_pos
++], 0);
1342 // Get Number of Records
1343 lzma_vli number_of_records
= 0;
1344 lzma_vli block_count
= 0;
1345 assert_lzma_ret(lzma_vli_decode(&number_of_records
, NULL
, buffer
,
1346 &buffer_pos
, buffer_size
), LZMA_OK
);
1348 while (!lzma_index_iter_next(&iter
, LZMA_INDEX_ITER_ANY
)) {
1349 // Verify each Record (Unpadded Size, then Uncompressed Size).
1350 // Verify Unpadded Size.
1351 lzma_vli unpadded_size
, uncompressed_size
;
1352 assert_lzma_ret(lzma_vli_decode(&unpadded_size
,
1353 NULL
, buffer
, &buffer_pos
,
1354 buffer_size
), LZMA_OK
);
1355 assert_uint_eq(unpadded_size
,
1356 iter
.block
.unpadded_size
);
1358 // Verify Uncompressed Size
1359 assert_lzma_ret(lzma_vli_decode(&uncompressed_size
,
1360 NULL
, buffer
, &buffer_pos
,
1361 buffer_size
), LZMA_OK
);
1362 assert_uint_eq(uncompressed_size
,
1363 iter
.block
.uncompressed_size
);
1368 // Verify Number of Records
1369 assert_uint_eq(number_of_records
, block_count
);
1371 // Verify Index Padding
1372 for (; buffer_pos
% 4 != 0; buffer_pos
++)
1373 assert_uint_eq(buffer
[buffer_pos
], 0);
1376 uint32_t crc32
= lzma_crc32(buffer
, buffer_pos
, 0);
1377 assert_uint_eq(read32le(buffer
+ buffer_pos
), crc32
);
1381 // In a few places the Index size is needed as a size_t but lzma_index_size()
1382 // returns lzma_vli.
1384 get_index_size(const lzma_index
*idx
)
1386 const lzma_vli size
= lzma_index_size(idx
);
1387 assert_uint(size
, <, SIZE_MAX
);
1388 return (size_t)size
;
1394 test_lzma_index_encoder(void)
1396 #if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
1397 assert_skip("Encoder or decoder support disabled");
1399 lzma_index
*idx
= lzma_index_init(NULL
);
1400 assert_true(idx
!= NULL
);
1402 lzma_stream strm
= LZMA_STREAM_INIT
;
1404 // First do basic NULL checks
1405 assert_lzma_ret(lzma_index_encoder(NULL
, NULL
), LZMA_PROG_ERROR
);
1406 assert_lzma_ret(lzma_index_encoder(&strm
, NULL
), LZMA_PROG_ERROR
);
1407 assert_lzma_ret(lzma_index_encoder(NULL
, idx
), LZMA_PROG_ERROR
);
1409 // Append three small Blocks
1410 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1411 UNPADDED_SIZE_MIN
, 10), LZMA_OK
);
1412 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1413 UNPADDED_SIZE_MIN
* 2, 100), LZMA_OK
);
1414 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1415 UNPADDED_SIZE_MIN
* 3, 1000), LZMA_OK
);
1417 // Encode this lzma_index into a buffer
1418 size_t buffer_size
= get_index_size(idx
);
1419 uint8_t *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);
1431 verify_index_buffer(idx
, buffer
, buffer_size
);
1433 // Test with multiple Streams concatenated into 1 Index
1434 lzma_index
*second
= lzma_index_init(NULL
);
1435 assert_true(second
!= NULL
);
1438 assert_lzma_ret(lzma_index_append(second
, NULL
,
1439 UNPADDED_SIZE_MIN
* 4, 20), LZMA_OK
);
1441 // Include Stream Padding
1442 assert_lzma_ret(lzma_index_stream_padding(second
, 16), LZMA_OK
);
1444 assert_lzma_ret(lzma_index_cat(idx
, second
, NULL
), LZMA_OK
);
1445 buffer_size
= get_index_size(idx
);
1446 buffer
= tuktest_malloc(buffer_size
);
1447 assert_lzma_ret(lzma_index_encoder(&strm
, idx
), LZMA_OK
);
1449 strm
.avail_out
= buffer_size
;
1450 strm
.next_out
= buffer
;
1452 assert_lzma_ret(lzma_code(&strm
, LZMA_FINISH
), LZMA_STREAM_END
);
1453 assert_uint_eq(strm
.avail_out
, 0);
1455 verify_index_buffer(idx
, buffer
, buffer_size
);
1457 lzma_index_end(idx
, NULL
);
1463 generate_index_decode_buffer(void)
1465 #ifdef HAVE_ENCODERS
1466 decode_test_index
= lzma_index_init(NULL
);
1467 if (decode_test_index
== NULL
)
1471 for (uint32_t i
= 1; i
< 5; i
++)
1472 if (lzma_index_append(decode_test_index
, NULL
,
1473 0x1000 * i
, 0x100 * i
) != LZMA_OK
)
1476 size_t size
= lzma_index_size(decode_test_index
);
1477 decode_buffer
= tuktest_malloc(size
);
1479 if (lzma_index_buffer_encode(decode_test_index
,
1480 decode_buffer
, &decode_buffer_size
, size
) != LZMA_OK
)
1481 decode_buffer_size
= 0;
1486 #ifdef HAVE_DECODERS
1488 decode_index(const uint8_t *buffer
, const size_t size
, lzma_stream
*strm
,
1489 lzma_ret expected_error
)
1491 strm
->avail_in
= size
;
1492 strm
->next_in
= buffer
;
1493 assert_lzma_ret(lzma_code(strm
, LZMA_FINISH
), expected_error
);
1499 test_lzma_index_decoder(void)
1501 #ifndef HAVE_DECODERS
1502 assert_skip("Decoder support disabled");
1504 if (decode_buffer_size
== 0)
1505 assert_skip("Could not initialize decode test buffer");
1507 lzma_stream strm
= LZMA_STREAM_INIT
;
1509 assert_lzma_ret(lzma_index_decoder(NULL
, NULL
, MEMLIMIT
),
1511 assert_lzma_ret(lzma_index_decoder(&strm
, NULL
, MEMLIMIT
),
1513 assert_lzma_ret(lzma_index_decoder(NULL
, &decode_test_index
,
1514 MEMLIMIT
), LZMA_PROG_ERROR
);
1518 assert_lzma_ret(lzma_index_decoder(&strm
, &idx
, MEMLIMIT
),
1521 decode_index(decode_buffer
, decode_buffer_size
, &strm
,
1524 // Compare results with expected
1525 assert_true(index_is_equal(decode_test_index
, idx
));
1527 lzma_index_end(idx
, NULL
);
1529 // Test again with too low memory limit
1530 assert_lzma_ret(lzma_index_decoder(&strm
, &idx
, 0), LZMA_OK
);
1532 decode_index(decode_buffer
, decode_buffer_size
, &strm
,
1533 LZMA_MEMLIMIT_ERROR
);
1535 uint8_t *corrupt_buffer
= tuktest_malloc(decode_buffer_size
);
1536 memcpy(corrupt_buffer
, decode_buffer
, decode_buffer_size
);
1538 assert_lzma_ret(lzma_index_decoder(&strm
, &idx
, MEMLIMIT
),
1541 // First corrupt the Index Indicator
1542 corrupt_buffer
[0] ^= 1;
1543 decode_index(corrupt_buffer
, decode_buffer_size
, &strm
,
1545 corrupt_buffer
[0] ^= 1;
1547 // Corrupt something in the middle of Index
1548 corrupt_buffer
[decode_buffer_size
/ 2] ^= 1;
1549 assert_lzma_ret(lzma_index_decoder(&strm
, &idx
, MEMLIMIT
),
1551 decode_index(corrupt_buffer
, decode_buffer_size
, &strm
,
1553 corrupt_buffer
[decode_buffer_size
/ 2] ^= 1;
1556 corrupt_buffer
[decode_buffer_size
- 1] ^= 1;
1557 assert_lzma_ret(lzma_index_decoder(&strm
, &idx
, MEMLIMIT
),
1559 decode_index(corrupt_buffer
, decode_buffer_size
, &strm
,
1561 corrupt_buffer
[decode_buffer_size
- 1] ^= 1;
1563 // Corrupt Index Padding by setting it to non-zero
1564 corrupt_buffer
[decode_buffer_size
- 5] ^= 1;
1565 assert_lzma_ret(lzma_index_decoder(&strm
, &idx
, MEMLIMIT
),
1567 decode_index(corrupt_buffer
, decode_buffer_size
, &strm
,
1569 corrupt_buffer
[decode_buffer_size
- 1] ^= 1;
1577 test_lzma_index_buffer_encode(void)
1579 #if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
1580 assert_skip("Encoder or decoder support disabled");
1582 // More simple test than test_lzma_index_encoder() because
1583 // currently lzma_index_buffer_encode() is mostly a wrapper
1584 // around lzma_index_encoder() anyway.
1585 lzma_index
*idx
= lzma_index_init(NULL
);
1586 assert_true(idx
!= NULL
);
1588 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1589 UNPADDED_SIZE_MIN
, 10), LZMA_OK
);
1590 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1591 UNPADDED_SIZE_MIN
* 2, 100), LZMA_OK
);
1592 assert_lzma_ret(lzma_index_append(idx
, NULL
,
1593 UNPADDED_SIZE_MIN
* 3, 1000), LZMA_OK
);
1595 size_t buffer_size
= get_index_size(idx
);
1596 uint8_t *buffer
= tuktest_malloc(buffer_size
);
1599 // First test bad arguments
1600 assert_lzma_ret(lzma_index_buffer_encode(NULL
, NULL
, NULL
, 0),
1602 assert_lzma_ret(lzma_index_buffer_encode(idx
, NULL
, NULL
, 0),
1604 assert_lzma_ret(lzma_index_buffer_encode(idx
, buffer
, NULL
, 0),
1606 assert_lzma_ret(lzma_index_buffer_encode(idx
, buffer
, &out_pos
,
1607 0), LZMA_PROG_ERROR
);
1609 assert_lzma_ret(lzma_index_buffer_encode(idx
, buffer
, &out_pos
,
1610 1), LZMA_BUF_ERROR
);
1613 assert_lzma_ret(lzma_index_buffer_encode(idx
, buffer
, &out_pos
,
1614 buffer_size
), LZMA_OK
);
1615 assert_uint_eq(out_pos
, buffer_size
);
1618 verify_index_buffer(idx
, buffer
, buffer_size
);
1620 lzma_index_end(idx
, NULL
);
1626 test_lzma_index_buffer_decode(void)
1628 #ifndef HAVE_DECODERS
1629 assert_skip("Decoder support disabled");
1631 if (decode_buffer_size
== 0)
1632 assert_skip("Could not initialize decode test buffer");
1634 // Simple test since test_lzma_index_decoder() covers most of the
1635 // lzma_index_buffer_decode() code anyway.
1637 // First test NULL checks
1638 assert_lzma_ret(lzma_index_buffer_decode(NULL
, NULL
, NULL
, NULL
,
1639 NULL
, 0), LZMA_PROG_ERROR
);
1642 uint64_t memlimit
= MEMLIMIT
;
1645 assert_lzma_ret(lzma_index_buffer_decode(&idx
, NULL
, NULL
, NULL
,
1646 NULL
, 0), LZMA_PROG_ERROR
);
1648 assert_lzma_ret(lzma_index_buffer_decode(&idx
, &memlimit
, NULL
,
1649 NULL
, NULL
, 0), LZMA_PROG_ERROR
);
1651 assert_lzma_ret(lzma_index_buffer_decode(&idx
, &memlimit
, NULL
,
1652 decode_buffer
, NULL
, 0), LZMA_PROG_ERROR
);
1654 assert_lzma_ret(lzma_index_buffer_decode(&idx
, &memlimit
, NULL
,
1655 decode_buffer
, NULL
, 0), LZMA_PROG_ERROR
);
1657 assert_lzma_ret(lzma_index_buffer_decode(&idx
, &memlimit
, NULL
,
1658 decode_buffer
, &in_pos
, 0), LZMA_DATA_ERROR
);
1661 assert_lzma_ret(lzma_index_buffer_decode(&idx
, &memlimit
, NULL
,
1662 decode_buffer
, &in_pos
, 0), LZMA_PROG_ERROR
);
1665 // Test expected successful decode
1666 assert_lzma_ret(lzma_index_buffer_decode(&idx
, &memlimit
, NULL
,
1667 decode_buffer
, &in_pos
, decode_buffer_size
), LZMA_OK
);
1669 assert_true(index_is_equal(decode_test_index
, idx
));
1671 lzma_index_end(idx
, NULL
);
1673 // Test too small memlimit
1676 assert_lzma_ret(lzma_index_buffer_decode(&idx
, &memlimit
, NULL
,
1677 decode_buffer
, &in_pos
, decode_buffer_size
),
1678 LZMA_MEMLIMIT_ERROR
);
1679 assert_uint(memlimit
, >, 1);
1680 assert_uint(memlimit
, <, MEMLIMIT
);
1686 main(int argc
, char **argv
)
1688 tuktest_start(argc
, argv
);
1689 generate_index_decode_buffer();
1690 tuktest_run(test_lzma_index_memusage
);
1691 tuktest_run(test_lzma_index_memused
);
1692 tuktest_run(test_lzma_index_append
);
1693 tuktest_run(test_lzma_index_stream_flags
);
1694 tuktest_run(test_lzma_index_checks
);
1695 tuktest_run(test_lzma_index_stream_padding
);
1696 tuktest_run(test_lzma_index_stream_count
);
1697 tuktest_run(test_lzma_index_block_count
);
1698 tuktest_run(test_lzma_index_size
);
1699 tuktest_run(test_lzma_index_stream_size
);
1700 tuktest_run(test_lzma_index_total_size
);
1701 tuktest_run(test_lzma_index_file_size
);
1702 tuktest_run(test_lzma_index_uncompressed_size
);
1703 tuktest_run(test_lzma_index_iter_init
);
1704 tuktest_run(test_lzma_index_iter_rewind
);
1705 tuktest_run(test_lzma_index_iter_next
);
1706 tuktest_run(test_lzma_index_iter_locate
);
1707 tuktest_run(test_lzma_index_cat
);
1708 tuktest_run(test_lzma_index_dup
);
1709 tuktest_run(test_lzma_index_encoder
);
1710 tuktest_run(test_lzma_index_decoder
);
1711 tuktest_run(test_lzma_index_buffer_encode
);
1712 tuktest_run(test_lzma_index_buffer_decode
);
1713 lzma_index_end(decode_test_index
, NULL
);
1714 return tuktest_end();