Remove building with NOCRYPTO option
[minix.git] / external / public-domain / xz / dist / tests / test_index.c
blob06b4d6ba99e92842e2d501c92e2dd97edd99c2d4
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file test_index.c
4 /// \brief Tests functions handling the lzma_index structure
5 //
6 // Author: Lasse Collin
7 //
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
11 ///////////////////////////////////////////////////////////////////////////////
13 #include "tests.h"
15 #define MEMLIMIT (LZMA_VLI_C(1) << 20)
17 #define SMALL_COUNT 3
18 #define BIG_COUNT 5555
21 static lzma_index *
22 create_empty(void)
24 lzma_index *i = lzma_index_init(NULL);
25 expect(i != NULL);
26 return i;
30 static lzma_index *
31 create_small(void)
33 lzma_index *i = lzma_index_init(NULL);
34 expect(i != NULL);
35 expect(lzma_index_append(i, NULL, 101, 555) == LZMA_OK);
36 expect(lzma_index_append(i, NULL, 602, 777) == LZMA_OK);
37 expect(lzma_index_append(i, NULL, 804, 999) == LZMA_OK);
38 return i;
42 static lzma_index *
43 create_big(void)
45 lzma_index *i = lzma_index_init(NULL);
46 expect(i != NULL);
48 lzma_vli total_size = 0;
49 lzma_vli uncompressed_size = 0;
51 // Add pseudo-random sizes (but always the same size values).
52 uint32_t n = 11;
53 for (size_t j = 0; j < BIG_COUNT; ++j) {
54 n = 7019 * n + 7607;
55 const uint32_t t = n * 3011;
56 expect(lzma_index_append(i, NULL, t, n) == LZMA_OK);
57 total_size += (t + 3) & ~LZMA_VLI_C(3);
58 uncompressed_size += n;
61 expect(lzma_index_block_count(i) == BIG_COUNT);
62 expect(lzma_index_total_size(i) == total_size);
63 expect(lzma_index_uncompressed_size(i) == uncompressed_size);
64 expect(lzma_index_total_size(i) + lzma_index_size(i)
65 + 2 * LZMA_STREAM_HEADER_SIZE
66 == lzma_index_stream_size(i));
68 return i;
72 static bool
73 is_equal(const lzma_index *a, const lzma_index *b)
75 // Compare only the Stream and Block sizes and offsets.
76 lzma_index_iter ra, rb;
77 lzma_index_iter_init(&ra, a);
78 lzma_index_iter_init(&rb, b);
80 while (true) {
81 bool reta = lzma_index_iter_next(&ra, LZMA_INDEX_ITER_ANY);
82 bool retb = lzma_index_iter_next(&rb, LZMA_INDEX_ITER_ANY);
83 if (reta)
84 return !(reta ^ retb);
86 if (ra.stream.number != rb.stream.number
87 || ra.stream.block_count
88 != rb.stream.block_count
89 || ra.stream.compressed_offset
90 != rb.stream.compressed_offset
91 || ra.stream.uncompressed_offset
92 != rb.stream.uncompressed_offset
93 || ra.stream.compressed_size
94 != rb.stream.compressed_size
95 || ra.stream.uncompressed_size
96 != rb.stream.uncompressed_size
97 || ra.stream.padding
98 != rb.stream.padding)
99 return false;
101 if (ra.stream.block_count == 0)
102 continue;
104 if (ra.block.number_in_file != rb.block.number_in_file
105 || ra.block.compressed_file_offset
106 != rb.block.compressed_file_offset
107 || ra.block.uncompressed_file_offset
108 != rb.block.uncompressed_file_offset
109 || ra.block.number_in_stream
110 != rb.block.number_in_stream
111 || ra.block.compressed_stream_offset
112 != rb.block.compressed_stream_offset
113 || ra.block.uncompressed_stream_offset
114 != rb.block.uncompressed_stream_offset
115 || ra.block.uncompressed_size
116 != rb.block.uncompressed_size
117 || ra.block.unpadded_size
118 != rb.block.unpadded_size
119 || ra.block.total_size
120 != rb.block.total_size)
121 return false;
126 static void
127 test_equal(void)
129 lzma_index *a = create_empty();
130 lzma_index *b = create_small();
131 lzma_index *c = create_big();
132 expect(a && b && c);
134 expect(is_equal(a, a));
135 expect(is_equal(b, b));
136 expect(is_equal(c, c));
138 expect(!is_equal(a, b));
139 expect(!is_equal(a, c));
140 expect(!is_equal(b, c));
142 lzma_index_end(a, NULL);
143 lzma_index_end(b, NULL);
144 lzma_index_end(c, NULL);
148 static void
149 test_overflow(void)
151 // Integer overflow tests
152 lzma_index *i = create_empty();
154 expect(lzma_index_append(i, NULL, LZMA_VLI_MAX - 5, 1234)
155 == LZMA_DATA_ERROR);
157 // TODO
159 lzma_index_end(i, NULL);
163 static void
164 test_copy(const lzma_index *i)
166 lzma_index *d = lzma_index_dup(i, NULL);
167 expect(d != NULL);
168 expect(is_equal(i, d));
169 lzma_index_end(d, NULL);
173 static void
174 test_read(lzma_index *i)
176 lzma_index_iter r;
177 lzma_index_iter_init(&r, i);
179 // Try twice so we see that rewinding works.
180 for (size_t j = 0; j < 2; ++j) {
181 lzma_vli total_size = 0;
182 lzma_vli uncompressed_size = 0;
183 lzma_vli stream_offset = LZMA_STREAM_HEADER_SIZE;
184 lzma_vli uncompressed_offset = 0;
185 uint32_t count = 0;
187 while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)) {
188 ++count;
190 total_size += r.block.total_size;
191 uncompressed_size += r.block.uncompressed_size;
193 expect(r.block.compressed_file_offset
194 == stream_offset);
195 expect(r.block.uncompressed_file_offset
196 == uncompressed_offset);
198 stream_offset += r.block.total_size;
199 uncompressed_offset += r.block.uncompressed_size;
202 expect(lzma_index_total_size(i) == total_size);
203 expect(lzma_index_uncompressed_size(i) == uncompressed_size);
204 expect(lzma_index_block_count(i) == count);
206 lzma_index_iter_rewind(&r);
211 static void
212 test_code(lzma_index *i)
214 const size_t alloc_size = 128 * 1024;
215 uint8_t *buf = malloc(alloc_size);
216 expect(buf != NULL);
218 // Encode
219 lzma_stream strm = LZMA_STREAM_INIT;
220 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
221 const lzma_vli index_size = lzma_index_size(i);
222 succeed(coder_loop(&strm, NULL, 0, buf, index_size,
223 LZMA_STREAM_END, LZMA_RUN));
225 // Decode
226 lzma_index *d;
227 expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK);
228 expect(d == NULL);
229 succeed(decoder_loop(&strm, buf, index_size));
231 expect(is_equal(i, d));
233 lzma_index_end(d, NULL);
234 lzma_end(&strm);
236 // Decode with hashing
237 lzma_index_hash *h = lzma_index_hash_init(NULL, NULL);
238 expect(h != NULL);
239 lzma_index_iter r;
240 lzma_index_iter_init(&r, i);
241 while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK))
242 expect(lzma_index_hash_append(h, r.block.unpadded_size,
243 r.block.uncompressed_size) == LZMA_OK);
244 size_t pos = 0;
245 while (pos < index_size - 1)
246 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
247 == LZMA_OK);
248 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
249 == LZMA_STREAM_END);
251 lzma_index_hash_end(h, NULL);
253 // Encode buffer
254 size_t buf_pos = 1;
255 expect(lzma_index_buffer_encode(i, buf, &buf_pos, index_size)
256 == LZMA_BUF_ERROR);
257 expect(buf_pos == 1);
259 succeed(lzma_index_buffer_encode(i, buf, &buf_pos, index_size + 1));
260 expect(buf_pos == index_size + 1);
262 // Decode buffer
263 buf_pos = 1;
264 uint64_t memlimit = MEMLIMIT;
265 expect(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
266 index_size) == LZMA_DATA_ERROR);
267 expect(buf_pos == 1);
268 expect(d == NULL);
270 succeed(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
271 index_size + 1));
272 expect(buf_pos == index_size + 1);
273 expect(is_equal(i, d));
275 lzma_index_end(d, NULL);
277 free(buf);
281 static void
282 test_many(lzma_index *i)
284 test_copy(i);
285 test_read(i);
286 test_code(i);
290 static void
291 test_cat(void)
293 lzma_index *a, *b, *c;
294 lzma_index_iter r;
296 // Empty Indexes
297 a = create_empty();
298 b = create_empty();
299 expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
300 expect(lzma_index_block_count(a) == 0);
301 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
302 expect(lzma_index_file_size(a)
303 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
304 lzma_index_iter_init(&r, a);
305 expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
307 b = create_empty();
308 expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
309 expect(lzma_index_block_count(a) == 0);
310 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
311 expect(lzma_index_file_size(a)
312 == 3 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
314 b = create_empty();
315 c = create_empty();
316 expect(lzma_index_stream_padding(b, 4) == LZMA_OK);
317 expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
318 expect(lzma_index_block_count(b) == 0);
319 expect(lzma_index_stream_size(b) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
320 expect(lzma_index_file_size(b)
321 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4);
323 expect(lzma_index_stream_padding(a, 8) == LZMA_OK);
324 expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
325 expect(lzma_index_block_count(a) == 0);
326 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
327 expect(lzma_index_file_size(a)
328 == 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8);
330 expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
331 lzma_index_iter_rewind(&r);
332 expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
333 lzma_index_end(a, NULL);
335 // Small Indexes
336 a = create_small();
337 lzma_vli stream_size = lzma_index_stream_size(a);
338 lzma_index_iter_init(&r, a);
339 for (int i = SMALL_COUNT; i >= 0; --i)
340 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
341 ^ (i == 0));
343 b = create_small();
344 expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
345 expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
346 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
347 expect(lzma_index_stream_size(a) > stream_size);
348 expect(lzma_index_stream_size(a) < stream_size * 2);
349 for (int i = SMALL_COUNT; i >= 0; --i)
350 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
351 ^ (i == 0));
353 lzma_index_iter_rewind(&r);
354 for (int i = SMALL_COUNT * 2; i >= 0; --i)
355 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
356 ^ (i == 0));
358 b = create_small();
359 c = create_small();
360 expect(lzma_index_stream_padding(b, 8) == LZMA_OK);
361 expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
362 expect(lzma_index_stream_padding(a, 12) == LZMA_OK);
363 expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
364 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
366 expect(lzma_index_block_count(a) == SMALL_COUNT * 4);
367 for (int i = SMALL_COUNT * 2; i >= 0; --i)
368 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
369 ^ (i == 0));
371 lzma_index_iter_rewind(&r);
372 for (int i = SMALL_COUNT * 4; i >= 0; --i)
373 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
374 ^ (i == 0));
376 lzma_index_end(a, NULL);
378 // Mix of empty and small
379 a = create_empty();
380 b = create_small();
381 expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
382 expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
383 lzma_index_iter_init(&r, a);
384 for (int i = SMALL_COUNT; i >= 0; --i)
385 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
386 ^ (i == 0));
388 lzma_index_end(a, NULL);
390 // Big Indexes
391 a = create_big();
392 stream_size = lzma_index_stream_size(a);
393 b = create_big();
394 expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
395 expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
396 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
397 expect(lzma_index_stream_size(a) > stream_size);
398 expect(lzma_index_stream_size(a) < stream_size * 2);
400 b = create_big();
401 c = create_big();
402 expect(lzma_index_stream_padding(b, 8) == LZMA_OK);
403 expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
404 expect(lzma_index_stream_padding(a, 12) == LZMA_OK);
405 expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
406 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
408 lzma_index_iter_init(&r, a);
409 for (int i = BIG_COUNT * 4; i >= 0; --i)
410 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
411 ^ (i == 0));
413 lzma_index_end(a, NULL);
417 static void
418 test_locate(void)
420 lzma_index *i = lzma_index_init(NULL);
421 expect(i != NULL);
422 lzma_index_iter r;
423 lzma_index_iter_init(&r, i);
425 // Cannot locate anything from an empty Index.
426 expect(lzma_index_iter_locate(&r, 0));
427 expect(lzma_index_iter_locate(&r, 555));
429 // One empty Record: nothing is found since there's no uncompressed
430 // data.
431 expect(lzma_index_append(i, NULL, 16, 0) == LZMA_OK);
432 expect(lzma_index_iter_locate(&r, 0));
434 // Non-empty Record and we can find something.
435 expect(lzma_index_append(i, NULL, 32, 5) == LZMA_OK);
436 expect(!lzma_index_iter_locate(&r, 0));
437 expect(r.block.total_size == 32);
438 expect(r.block.uncompressed_size == 5);
439 expect(r.block.compressed_file_offset
440 == LZMA_STREAM_HEADER_SIZE + 16);
441 expect(r.block.uncompressed_file_offset == 0);
443 // Still cannot find anything past the end.
444 expect(lzma_index_iter_locate(&r, 5));
446 // Add the third Record.
447 expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK);
449 expect(!lzma_index_iter_locate(&r, 0));
450 expect(r.block.total_size == 32);
451 expect(r.block.uncompressed_size == 5);
452 expect(r.block.compressed_file_offset
453 == LZMA_STREAM_HEADER_SIZE + 16);
454 expect(r.block.uncompressed_file_offset == 0);
456 expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
457 expect(r.block.total_size == 40);
458 expect(r.block.uncompressed_size == 11);
459 expect(r.block.compressed_file_offset
460 == LZMA_STREAM_HEADER_SIZE + 16 + 32);
461 expect(r.block.uncompressed_file_offset == 5);
463 expect(!lzma_index_iter_locate(&r, 2));
464 expect(r.block.total_size == 32);
465 expect(r.block.uncompressed_size == 5);
466 expect(r.block.compressed_file_offset
467 == LZMA_STREAM_HEADER_SIZE + 16);
468 expect(r.block.uncompressed_file_offset == 0);
470 expect(!lzma_index_iter_locate(&r, 5));
471 expect(r.block.total_size == 40);
472 expect(r.block.uncompressed_size == 11);
473 expect(r.block.compressed_file_offset
474 == LZMA_STREAM_HEADER_SIZE + 16 + 32);
475 expect(r.block.uncompressed_file_offset == 5);
477 expect(!lzma_index_iter_locate(&r, 5 + 11 - 1));
478 expect(r.block.total_size == 40);
479 expect(r.block.uncompressed_size == 11);
480 expect(r.block.compressed_file_offset
481 == LZMA_STREAM_HEADER_SIZE + 16 + 32);
482 expect(r.block.uncompressed_file_offset == 5);
484 expect(lzma_index_iter_locate(&r, 5 + 11));
485 expect(lzma_index_iter_locate(&r, 5 + 15));
487 // Large Index
488 lzma_index_end(i, NULL);
489 i = lzma_index_init(NULL);
490 expect(i != NULL);
491 lzma_index_iter_init(&r, i);
493 for (size_t n = 4; n <= 4 * 5555; n += 4)
494 expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK);
496 expect(lzma_index_block_count(i) == 5555);
498 // First Record
499 expect(!lzma_index_iter_locate(&r, 0));
500 expect(r.block.total_size == 4 + 8);
501 expect(r.block.uncompressed_size == 4);
502 expect(r.block.compressed_file_offset == LZMA_STREAM_HEADER_SIZE);
503 expect(r.block.uncompressed_file_offset == 0);
505 expect(!lzma_index_iter_locate(&r, 3));
506 expect(r.block.total_size == 4 + 8);
507 expect(r.block.uncompressed_size == 4);
508 expect(r.block.compressed_file_offset == LZMA_STREAM_HEADER_SIZE);
509 expect(r.block.uncompressed_file_offset == 0);
511 // Second Record
512 expect(!lzma_index_iter_locate(&r, 4));
513 expect(r.block.total_size == 2 * 4 + 8);
514 expect(r.block.uncompressed_size == 2 * 4);
515 expect(r.block.compressed_file_offset
516 == LZMA_STREAM_HEADER_SIZE + 4 + 8);
517 expect(r.block.uncompressed_file_offset == 4);
519 // Last Record
520 expect(!lzma_index_iter_locate(
521 &r, lzma_index_uncompressed_size(i) - 1));
522 expect(r.block.total_size == 4 * 5555 + 8);
523 expect(r.block.uncompressed_size == 4 * 5555);
524 expect(r.block.compressed_file_offset == lzma_index_total_size(i)
525 + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
526 expect(r.block.uncompressed_file_offset
527 == lzma_index_uncompressed_size(i) - 4 * 5555);
529 // Allocation chunk boundaries. See INDEX_GROUP_SIZE in
530 // liblzma/common/index.c.
531 const size_t group_multiple = 256 * 4;
532 const size_t radius = 8;
533 const size_t start = group_multiple - radius;
534 lzma_vli ubase = 0;
535 lzma_vli tbase = 0;
536 size_t n;
537 for (n = 1; n < start; ++n) {
538 ubase += n * 4;
539 tbase += n * 4 + 8;
542 while (n < start + 2 * radius) {
543 expect(!lzma_index_iter_locate(&r, ubase + n * 4));
545 expect(r.block.compressed_file_offset == tbase + n * 4 + 8
546 + LZMA_STREAM_HEADER_SIZE);
547 expect(r.block.uncompressed_file_offset == ubase + n * 4);
549 tbase += n * 4 + 8;
550 ubase += n * 4;
551 ++n;
553 expect(r.block.total_size == n * 4 + 8);
554 expect(r.block.uncompressed_size == n * 4);
557 // Do it also backwards.
558 while (n > start) {
559 expect(!lzma_index_iter_locate(&r, ubase + (n - 1) * 4));
561 expect(r.block.total_size == n * 4 + 8);
562 expect(r.block.uncompressed_size == n * 4);
564 --n;
565 tbase -= n * 4 + 8;
566 ubase -= n * 4;
568 expect(r.block.compressed_file_offset == tbase + n * 4 + 8
569 + LZMA_STREAM_HEADER_SIZE);
570 expect(r.block.uncompressed_file_offset == ubase + n * 4);
573 // Test locating in concatenated Index.
574 lzma_index_end(i, NULL);
575 i = lzma_index_init(NULL);
576 expect(i != NULL);
577 lzma_index_iter_init(&r, i);
578 for (n = 0; n < group_multiple; ++n)
579 expect(lzma_index_append(i, NULL, 8, 0) == LZMA_OK);
580 expect(lzma_index_append(i, NULL, 16, 1) == LZMA_OK);
581 expect(!lzma_index_iter_locate(&r, 0));
582 expect(r.block.total_size == 16);
583 expect(r.block.uncompressed_size == 1);
584 expect(r.block.compressed_file_offset
585 == LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
586 expect(r.block.uncompressed_file_offset == 0);
588 lzma_index_end(i, NULL);
592 static void
593 test_corrupt(void)
595 const size_t alloc_size = 128 * 1024;
596 uint8_t *buf = malloc(alloc_size);
597 expect(buf != NULL);
598 lzma_stream strm = LZMA_STREAM_INIT;
600 lzma_index *i = create_empty();
601 expect(lzma_index_append(i, NULL, 0, 1) == LZMA_PROG_ERROR);
602 lzma_index_end(i, NULL);
604 // Create a valid Index and corrupt it in different ways.
605 i = create_small();
606 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
607 succeed(coder_loop(&strm, NULL, 0, buf, 20,
608 LZMA_STREAM_END, LZMA_RUN));
609 lzma_index_end(i, NULL);
611 // Wrong Index Indicator
612 buf[0] ^= 1;
613 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
614 succeed(decoder_loop_ret(&strm, buf, 1, LZMA_DATA_ERROR));
615 buf[0] ^= 1;
617 // Wrong Number of Records and thus CRC32 fails.
618 --buf[1];
619 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
620 succeed(decoder_loop_ret(&strm, buf, 10, LZMA_DATA_ERROR));
621 ++buf[1];
623 // Padding not NULs
624 buf[15] ^= 1;
625 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
626 succeed(decoder_loop_ret(&strm, buf, 16, LZMA_DATA_ERROR));
628 lzma_end(&strm);
629 free(buf);
634 main(void)
636 test_equal();
638 test_overflow();
640 lzma_index *i = create_empty();
641 test_many(i);
642 lzma_index_end(i, NULL);
644 i = create_small();
645 test_many(i);
646 lzma_index_end(i, NULL);
648 i = create_big();
649 test_many(i);
650 lzma_index_end(i, NULL);
652 test_cat();
654 test_locate();
656 test_corrupt();
658 return 0;