1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Tests functions handling the lzma_index structure
6 // Author: Lasse Collin
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
11 ///////////////////////////////////////////////////////////////////////////////
15 #define MEMLIMIT (LZMA_VLI_C(1) << 20)
18 #define BIG_COUNT 5555
24 lzma_index *i = lzma_index_init(NULL, NULL);
33 lzma_index *i = lzma_index_init(NULL, 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);
45 lzma_index *i = lzma_index_init(NULL, NULL);
48 lzma_vli total_size = 0;
49 lzma_vli uncompressed_size = 0;
51 // Add pseudo-random sizes (but always the same size values).
53 for (size_t j = 0; j < BIG_COUNT; ++j) {
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_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));
75 lzma_index *a = create_empty();
76 lzma_index *b = create_small();
77 lzma_index *c = create_big();
80 expect(lzma_index_equal(a, a));
81 expect(lzma_index_equal(b, b));
82 expect(lzma_index_equal(c, c));
84 expect(!lzma_index_equal(a, b));
85 expect(!lzma_index_equal(a, c));
86 expect(!lzma_index_equal(b, c));
88 lzma_index_end(a, NULL);
89 lzma_index_end(b, NULL);
90 lzma_index_end(c, NULL);
97 // Integer overflow tests
98 lzma_index *i = create_empty();
100 expect(lzma_index_append(i, NULL, LZMA_VLI_MAX - 5, 1234)
105 lzma_index_end(i, NULL);
110 test_copy(const lzma_index *i)
112 lzma_index *d = lzma_index_dup(i, NULL);
114 lzma_index_end(d, NULL);
119 test_read(lzma_index *i)
121 lzma_index_record record;
123 // Try twice so we see that rewinding works.
124 for (size_t j = 0; j < 2; ++j) {
125 lzma_vli total_size = 0;
126 lzma_vli uncompressed_size = 0;
127 lzma_vli stream_offset = LZMA_STREAM_HEADER_SIZE;
128 lzma_vli uncompressed_offset = 0;
131 while (!lzma_index_read(i, &record)) {
134 total_size += record.total_size;
135 uncompressed_size += record.uncompressed_size;
137 expect(record.stream_offset == stream_offset);
138 expect(record.uncompressed_offset
139 == uncompressed_offset);
141 stream_offset += record.total_size;
142 uncompressed_offset += record.uncompressed_size;
145 expect(lzma_index_total_size(i) == total_size);
146 expect(lzma_index_uncompressed_size(i) == uncompressed_size);
147 expect(lzma_index_count(i) == count);
149 lzma_index_rewind(i);
155 test_code(lzma_index *i)
157 const size_t alloc_size = 128 * 1024;
158 uint8_t *buf = malloc(alloc_size);
162 lzma_stream strm = LZMA_STREAM_INIT;
163 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
164 const lzma_vli index_size = lzma_index_size(i);
165 succeed(coder_loop(&strm, NULL, 0, buf, index_size,
166 LZMA_STREAM_END, LZMA_RUN));
170 expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK);
172 succeed(decoder_loop(&strm, buf, index_size));
174 expect(lzma_index_equal(i, d));
176 lzma_index_end(d, NULL);
179 // Decode with hashing
180 lzma_index_hash *h = lzma_index_hash_init(NULL, NULL);
182 lzma_index_rewind(i);
184 while (!lzma_index_read(i, &r))
185 expect(lzma_index_hash_append(h, r.unpadded_size,
186 r.uncompressed_size) == LZMA_OK);
188 while (pos < index_size - 1)
189 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
191 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
194 lzma_index_hash_end(h, NULL);
198 expect(lzma_index_buffer_encode(i, buf, &buf_pos, index_size)
200 expect(buf_pos == 1);
202 succeed(lzma_index_buffer_encode(i, buf, &buf_pos, index_size + 1));
203 expect(buf_pos == index_size + 1);
207 uint64_t memlimit = MEMLIMIT;
208 expect(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
209 index_size) == LZMA_DATA_ERROR);
210 expect(buf_pos == 1);
213 succeed(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
215 expect(buf_pos == index_size + 1);
216 expect(lzma_index_equal(i, d));
218 lzma_index_end(d, NULL);
225 test_many(lzma_index *i)
236 lzma_index *a, *b, *c;
242 expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
243 expect(lzma_index_count(a) == 0);
244 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
245 expect(lzma_index_file_size(a)
246 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
247 expect(lzma_index_read(a, &r));
250 expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
251 expect(lzma_index_count(a) == 0);
252 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
253 expect(lzma_index_file_size(a)
254 == 3 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
258 expect(lzma_index_cat(b, c, NULL, 4) == LZMA_OK);
259 expect(lzma_index_count(b) == 0);
260 expect(lzma_index_stream_size(b) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
261 expect(lzma_index_file_size(b)
262 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4);
264 expect(lzma_index_cat(a, b, NULL, 8) == LZMA_OK);
265 expect(lzma_index_count(a) == 0);
266 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
267 expect(lzma_index_file_size(a)
268 == 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8);
270 expect(lzma_index_read(a, &r));
271 lzma_index_rewind(a);
272 expect(lzma_index_read(a, &r));
273 lzma_index_end(a, NULL);
277 lzma_vli stream_size = lzma_index_stream_size(a);
279 expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK);
280 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
281 expect(lzma_index_stream_size(a) > stream_size);
282 expect(lzma_index_stream_size(a) < stream_size * 2);
286 expect(lzma_index_cat(b, c, NULL, 8) == LZMA_OK);
287 expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK);
288 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
290 expect(lzma_index_count(a) == SMALL_COUNT * 4);
291 for (int i = SMALL_COUNT * 4; i >= 0; --i)
292 expect(!lzma_index_read(a, &r) ^ (i == 0));
294 lzma_index_end(a, NULL);
296 // Mix of empty and small
299 expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK);
300 for (int i = SMALL_COUNT; i >= 0; --i)
301 expect(!lzma_index_read(a, &r) ^ (i == 0));
303 lzma_index_end(a, NULL);
307 stream_size = lzma_index_stream_size(a);
309 expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK);
310 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
311 expect(lzma_index_stream_size(a) > stream_size);
312 expect(lzma_index_stream_size(a) < stream_size * 2);
316 expect(lzma_index_cat(b, c, NULL, 8) == LZMA_OK);
317 expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK);
318 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
320 for (int i = BIG_COUNT * 4; i >= 0; --i)
321 expect(!lzma_index_read(a, &r) ^ (i == 0));
323 lzma_index_end(a, NULL);
331 lzma_index *i = lzma_index_init(NULL, NULL);
334 // Cannot locate anything from an empty Index.
335 expect(lzma_index_locate(i, &r, 0));
336 expect(lzma_index_locate(i, &r, 555));
338 // One empty Record: nothing is found since there's no uncompressed
340 expect(lzma_index_append(i, NULL, 16, 0) == LZMA_OK);
341 expect(lzma_index_locate(i, &r, 0));
343 // Non-empty Record and we can find something.
344 expect(lzma_index_append(i, NULL, 32, 5) == LZMA_OK);
345 expect(!lzma_index_locate(i, &r, 0));
346 expect(r.total_size == 32);
347 expect(r.uncompressed_size == 5);
348 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
349 expect(r.uncompressed_offset == 0);
351 // Still cannot find anything past the end.
352 expect(lzma_index_locate(i, &r, 5));
354 // Add the third Record.
355 expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK);
357 expect(!lzma_index_locate(i, &r, 0));
358 expect(r.total_size == 32);
359 expect(r.uncompressed_size == 5);
360 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
361 expect(r.uncompressed_offset == 0);
363 expect(!lzma_index_read(i, &r));
364 expect(r.total_size == 40);
365 expect(r.uncompressed_size == 11);
366 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
367 expect(r.uncompressed_offset == 5);
369 expect(!lzma_index_locate(i, &r, 2));
370 expect(r.total_size == 32);
371 expect(r.uncompressed_size == 5);
372 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
373 expect(r.uncompressed_offset == 0);
375 expect(!lzma_index_locate(i, &r, 5));
376 expect(r.total_size == 40);
377 expect(r.uncompressed_size == 11);
378 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
379 expect(r.uncompressed_offset == 5);
381 expect(!lzma_index_locate(i, &r, 5 + 11 - 1));
382 expect(r.total_size == 40);
383 expect(r.uncompressed_size == 11);
384 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
385 expect(r.uncompressed_offset == 5);
387 expect(lzma_index_locate(i, &r, 5 + 11));
388 expect(lzma_index_locate(i, &r, 5 + 15));
391 i = lzma_index_init(i, NULL);
394 for (size_t n = 4; n <= 4 * 5555; n += 4)
395 expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK);
397 expect(lzma_index_count(i) == 5555);
400 expect(!lzma_index_locate(i, &r, 0));
401 expect(r.total_size == 4 + 8);
402 expect(r.uncompressed_size == 4);
403 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE);
404 expect(r.uncompressed_offset == 0);
406 expect(!lzma_index_locate(i, &r, 3));
407 expect(r.total_size == 4 + 8);
408 expect(r.uncompressed_size == 4);
409 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE);
410 expect(r.uncompressed_offset == 0);
413 expect(!lzma_index_locate(i, &r, 4));
414 expect(r.total_size == 2 * 4 + 8);
415 expect(r.uncompressed_size == 2 * 4);
416 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 4 + 8);
417 expect(r.uncompressed_offset == 4);
420 expect(!lzma_index_locate(i, &r, lzma_index_uncompressed_size(i) - 1));
421 expect(r.total_size == 4 * 5555 + 8);
422 expect(r.uncompressed_size == 4 * 5555);
423 expect(r.stream_offset == lzma_index_total_size(i)
424 + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
425 expect(r.uncompressed_offset
426 == lzma_index_uncompressed_size(i) - 4 * 5555);
428 // Allocation chunk boundaries. See INDEX_GROUP_SIZE in
429 // liblzma/common/index.c.
430 const size_t group_multiple = 256 * 4;
431 const size_t radius = 8;
432 const size_t start = group_multiple - radius;
436 for (n = 1; n < start; ++n) {
441 while (n < start + 2 * radius) {
442 expect(!lzma_index_locate(i, &r, ubase + n * 4));
444 expect(r.stream_offset == tbase + n * 4 + 8
445 + LZMA_STREAM_HEADER_SIZE);
446 expect(r.uncompressed_offset == ubase + n * 4);
452 expect(r.total_size == n * 4 + 8);
453 expect(r.uncompressed_size == n * 4);
456 // Do it also backwards since lzma_index_locate() uses relative search.
458 expect(!lzma_index_locate(i, &r, ubase + (n - 1) * 4));
460 expect(r.total_size == n * 4 + 8);
461 expect(r.uncompressed_size == n * 4);
467 expect(r.stream_offset == tbase + n * 4 + 8
468 + LZMA_STREAM_HEADER_SIZE);
469 expect(r.uncompressed_offset == ubase + n * 4);
472 // Test locating in concatend Index.
473 i = lzma_index_init(i, NULL);
475 for (n = 0; n < group_multiple; ++n)
476 expect(lzma_index_append(i, NULL, 8, 0) == LZMA_OK);
477 expect(lzma_index_append(i, NULL, 16, 1) == LZMA_OK);
478 expect(!lzma_index_locate(i, &r, 0));
479 expect(r.total_size == 16);
480 expect(r.uncompressed_size == 1);
481 expect(r.stream_offset
482 == LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
483 expect(r.uncompressed_offset == 0);
485 lzma_index_end(i, NULL);
492 const size_t alloc_size = 128 * 1024;
493 uint8_t *buf = malloc(alloc_size);
495 lzma_stream strm = LZMA_STREAM_INIT;
497 lzma_index *i = create_empty();
498 expect(lzma_index_append(i, NULL, 0, 1) == LZMA_PROG_ERROR);
499 lzma_index_end(i, NULL);
501 // Create a valid Index and corrupt it in different ways.
503 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
504 succeed(coder_loop(&strm, NULL, 0, buf, 20,
505 LZMA_STREAM_END, LZMA_RUN));
506 lzma_index_end(i, NULL);
508 // Wrong Index Indicator
510 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
511 succeed(decoder_loop_ret(&strm, buf, 1, LZMA_DATA_ERROR));
514 // Wrong Number of Records and thus CRC32 fails.
516 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
517 succeed(decoder_loop_ret(&strm, buf, 10, LZMA_DATA_ERROR));
522 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
523 succeed(decoder_loop_ret(&strm, buf, 16, LZMA_DATA_ERROR));
537 lzma_index *i = create_empty();
539 lzma_index_end(i, NULL);
543 lzma_index_end(i, NULL);
547 lzma_index_end(i, NULL);