1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Tests functions handling the lzma_index structure
6 // Copyright (C) 2007-2008 Lasse Collin
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 ///////////////////////////////////////////////////////////////////////////////
22 #define MEMLIMIT (LZMA_VLI_C(1) << 20)
28 lzma_index *i = lzma_index_init(NULL, NULL);
37 lzma_index *i = lzma_index_init(NULL, NULL);
39 expect(lzma_index_append(i, NULL, 101, 555) == LZMA_OK);
40 expect(lzma_index_append(i, NULL, 602, 777) == LZMA_OK);
41 expect(lzma_index_append(i, NULL, 804, 999) == LZMA_OK);
49 lzma_index *i = lzma_index_init(NULL, NULL);
52 lzma_vli total_size = 0;
53 lzma_vli uncompressed_size = 0;
55 // Add pseudo-random sizes (but always the same size values).
56 const size_t count = 5555;
58 for (size_t j = 0; j < count; ++j) {
60 const uint32_t t = n * 3011;
61 expect(lzma_index_append(i, NULL, t, n) == LZMA_OK);
62 total_size += (t + 3) & ~LZMA_VLI_C(3);
63 uncompressed_size += n;
66 expect(lzma_index_count(i) == count);
67 expect(lzma_index_total_size(i) == total_size);
68 expect(lzma_index_uncompressed_size(i) == uncompressed_size);
69 expect(lzma_index_total_size(i) + lzma_index_size(i)
70 + 2 * LZMA_STREAM_HEADER_SIZE
71 == lzma_index_stream_size(i));
80 lzma_index *a = create_empty();
81 lzma_index *b = create_small();
82 lzma_index *c = create_big();
85 expect(lzma_index_equal(a, a));
86 expect(lzma_index_equal(b, b));
87 expect(lzma_index_equal(c, c));
89 expect(!lzma_index_equal(a, b));
90 expect(!lzma_index_equal(a, c));
91 expect(!lzma_index_equal(b, c));
93 lzma_index_end(a, NULL);
94 lzma_index_end(b, NULL);
95 lzma_index_end(c, NULL);
102 // Integer overflow tests
103 lzma_index *i = create_empty();
105 expect(lzma_index_append(i, NULL, LZMA_VLI_MAX - 5, 1234)
110 lzma_index_end(i, NULL);
115 test_copy(const lzma_index *i)
117 lzma_index *d = lzma_index_dup(i, NULL);
119 lzma_index_end(d, NULL);
124 test_read(lzma_index *i)
126 lzma_index_record record;
128 // Try twice so we see that rewinding works.
129 for (size_t j = 0; j < 2; ++j) {
130 lzma_vli total_size = 0;
131 lzma_vli uncompressed_size = 0;
132 lzma_vli stream_offset = LZMA_STREAM_HEADER_SIZE;
133 lzma_vli uncompressed_offset = 0;
136 while (!lzma_index_read(i, &record)) {
139 total_size += record.total_size;
140 uncompressed_size += record.uncompressed_size;
142 expect(record.stream_offset == stream_offset);
143 expect(record.uncompressed_offset
144 == uncompressed_offset);
146 stream_offset += record.total_size;
147 uncompressed_offset += record.uncompressed_size;
150 expect(lzma_index_total_size(i) == total_size);
151 expect(lzma_index_uncompressed_size(i) == uncompressed_size);
152 expect(lzma_index_count(i) == count);
154 lzma_index_rewind(i);
160 test_code(lzma_index *i)
162 const size_t alloc_size = 128 * 1024;
163 uint8_t *buf = malloc(alloc_size);
167 lzma_stream strm = LZMA_STREAM_INIT;
168 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
169 const lzma_vli index_size = lzma_index_size(i);
170 succeed(coder_loop(&strm, NULL, 0, buf, index_size,
171 LZMA_STREAM_END, LZMA_RUN));
175 expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK);
176 succeed(decoder_loop(&strm, buf, index_size));
178 expect(lzma_index_equal(i, d));
180 lzma_index_end(d, NULL);
183 // Decode with hashing
184 lzma_index_hash *h = lzma_index_hash_init(NULL, NULL);
186 lzma_index_rewind(i);
188 while (!lzma_index_read(i, &r))
189 expect(lzma_index_hash_append(h, r.unpadded_size,
190 r.uncompressed_size) == LZMA_OK);
192 while (pos < index_size - 1)
193 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
195 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
198 lzma_index_hash_end(h, NULL);
202 expect(lzma_index_buffer_encode(i, buf, &buf_pos, index_size)
204 expect(buf_pos == 1);
206 succeed(lzma_index_buffer_encode(i, buf, &buf_pos, index_size + 1));
207 expect(buf_pos == index_size + 1);
211 uint64_t memlimit = MEMLIMIT;
212 expect(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
213 index_size) == LZMA_DATA_ERROR);
214 expect(buf_pos == 1);
217 succeed(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
219 expect(buf_pos == index_size + 1);
220 expect(lzma_index_equal(i, d));
222 lzma_index_end(d, NULL);
229 test_many(lzma_index *i)
240 lzma_index *a, *b, *c;
245 expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
246 expect(lzma_index_count(a) == 0);
247 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
248 expect(lzma_index_file_size(a)
249 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
252 expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
253 expect(lzma_index_count(a) == 0);
254 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
255 expect(lzma_index_file_size(a)
256 == 3 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
260 expect(lzma_index_cat(b, c, NULL, 4) == LZMA_OK);
261 expect(lzma_index_count(b) == 0);
262 expect(lzma_index_stream_size(b) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
263 expect(lzma_index_file_size(b)
264 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4);
266 expect(lzma_index_cat(a, b, NULL, 8) == LZMA_OK);
267 expect(lzma_index_count(a) == 0);
268 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
269 expect(lzma_index_file_size(a)
270 == 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8);
272 lzma_index_end(a, NULL);
276 lzma_vli stream_size = lzma_index_stream_size(a);
278 expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK);
279 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
280 expect(lzma_index_stream_size(a) > stream_size);
281 expect(lzma_index_stream_size(a) < stream_size * 2);
285 expect(lzma_index_cat(b, c, NULL, 8) == LZMA_OK);
286 expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK);
287 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
289 lzma_index_end(a, NULL);
293 stream_size = lzma_index_stream_size(a);
295 expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK);
296 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
297 expect(lzma_index_stream_size(a) > stream_size);
298 expect(lzma_index_stream_size(a) < stream_size * 2);
302 expect(lzma_index_cat(b, c, NULL, 8) == LZMA_OK);
303 expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK);
304 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
306 lzma_index_end(a, NULL);
314 lzma_index *i = lzma_index_init(NULL, NULL);
317 // Cannot locate anything from an empty Index.
318 expect(lzma_index_locate(i, &r, 0));
319 expect(lzma_index_locate(i, &r, 555));
321 // One empty Record: nothing is found since there's no uncompressed
323 expect(lzma_index_append(i, NULL, 16, 0) == LZMA_OK);
324 expect(lzma_index_locate(i, &r, 0));
326 // Non-empty Record and we can find something.
327 expect(lzma_index_append(i, NULL, 32, 5) == LZMA_OK);
328 expect(!lzma_index_locate(i, &r, 0));
329 expect(r.total_size == 32);
330 expect(r.uncompressed_size == 5);
331 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
332 expect(r.uncompressed_offset == 0);
334 // Still cannot find anything past the end.
335 expect(lzma_index_locate(i, &r, 5));
337 // Add the third Record.
338 expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK);
340 expect(!lzma_index_locate(i, &r, 0));
341 expect(r.total_size == 32);
342 expect(r.uncompressed_size == 5);
343 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
344 expect(r.uncompressed_offset == 0);
346 expect(!lzma_index_read(i, &r));
347 expect(r.total_size == 40);
348 expect(r.uncompressed_size == 11);
349 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
350 expect(r.uncompressed_offset == 5);
352 expect(!lzma_index_locate(i, &r, 2));
353 expect(r.total_size == 32);
354 expect(r.uncompressed_size == 5);
355 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
356 expect(r.uncompressed_offset == 0);
358 expect(!lzma_index_locate(i, &r, 5));
359 expect(r.total_size == 40);
360 expect(r.uncompressed_size == 11);
361 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
362 expect(r.uncompressed_offset == 5);
364 expect(!lzma_index_locate(i, &r, 5 + 11 - 1));
365 expect(r.total_size == 40);
366 expect(r.uncompressed_size == 11);
367 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
368 expect(r.uncompressed_offset == 5);
370 expect(lzma_index_locate(i, &r, 5 + 11));
371 expect(lzma_index_locate(i, &r, 5 + 15));
374 i = lzma_index_init(i, NULL);
377 for (size_t n = 4; n <= 4 * 5555; n += 4)
378 expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK);
380 expect(lzma_index_count(i) == 5555);
383 expect(!lzma_index_locate(i, &r, 0));
384 expect(r.total_size == 4 + 8);
385 expect(r.uncompressed_size == 4);
386 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE);
387 expect(r.uncompressed_offset == 0);
389 expect(!lzma_index_locate(i, &r, 3));
390 expect(r.total_size == 4 + 8);
391 expect(r.uncompressed_size == 4);
392 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE);
393 expect(r.uncompressed_offset == 0);
396 expect(!lzma_index_locate(i, &r, 4));
397 expect(r.total_size == 2 * 4 + 8);
398 expect(r.uncompressed_size == 2 * 4);
399 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 4 + 8);
400 expect(r.uncompressed_offset == 4);
403 expect(!lzma_index_locate(i, &r, lzma_index_uncompressed_size(i) - 1));
404 expect(r.total_size == 4 * 5555 + 8);
405 expect(r.uncompressed_size == 4 * 5555);
406 expect(r.stream_offset == lzma_index_total_size(i)
407 + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
408 expect(r.uncompressed_offset
409 == lzma_index_uncompressed_size(i) - 4 * 5555);
411 // Allocation chunk boundaries. See INDEX_GROUP_SIZE in
412 // liblzma/common/index.c.
413 const size_t group_multiple = 256 * 4;
414 const size_t radius = 8;
415 const size_t start = group_multiple - radius;
419 for (n = 1; n < start; ++n) {
424 while (n < start + 2 * radius) {
425 expect(!lzma_index_locate(i, &r, ubase + n * 4));
427 expect(r.stream_offset == tbase + n * 4 + 8
428 + LZMA_STREAM_HEADER_SIZE);
429 expect(r.uncompressed_offset == ubase + n * 4);
435 expect(r.total_size == n * 4 + 8);
436 expect(r.uncompressed_size == n * 4);
439 // Do it also backwards since lzma_index_locate() uses relative search.
441 expect(!lzma_index_locate(i, &r, ubase + (n - 1) * 4));
443 expect(r.total_size == n * 4 + 8);
444 expect(r.uncompressed_size == n * 4);
450 expect(r.stream_offset == tbase + n * 4 + 8
451 + LZMA_STREAM_HEADER_SIZE);
452 expect(r.uncompressed_offset == ubase + n * 4);
455 // Test locating in concatend Index.
456 i = lzma_index_init(i, NULL);
458 for (n = 0; n < group_multiple; ++n)
459 expect(lzma_index_append(i, NULL, 8, 0) == LZMA_OK);
460 expect(lzma_index_append(i, NULL, 16, 1) == LZMA_OK);
461 expect(!lzma_index_locate(i, &r, 0));
462 expect(r.total_size == 16);
463 expect(r.uncompressed_size == 1);
464 expect(r.stream_offset
465 == LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
466 expect(r.uncompressed_offset == 0);
468 lzma_index_end(i, NULL);
475 const size_t alloc_size = 128 * 1024;
476 uint8_t *buf = malloc(alloc_size);
478 lzma_stream strm = LZMA_STREAM_INIT;
480 lzma_index *i = create_empty();
481 expect(lzma_index_append(i, NULL, 0, 1) == LZMA_PROG_ERROR);
482 lzma_index_end(i, NULL);
484 // Create a valid Index and corrupt it in different ways.
486 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
487 succeed(coder_loop(&strm, NULL, 0, buf, 20,
488 LZMA_STREAM_END, LZMA_RUN));
489 lzma_index_end(i, NULL);
491 // Wrong Index Indicator
493 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
494 succeed(decoder_loop_ret(&strm, buf, 1, LZMA_DATA_ERROR));
497 // Wrong Number of Records and thus CRC32 fails.
499 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
500 succeed(decoder_loop_ret(&strm, buf, 10, LZMA_DATA_ERROR));
505 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
506 succeed(decoder_loop_ret(&strm, buf, 16, LZMA_DATA_ERROR));
520 lzma_index *i = create_empty();
522 lzma_index_end(i, NULL);
526 lzma_index_end(i, NULL);
530 lzma_index_end(i, NULL);