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);
205 test_many(lzma_index *i)
216 lzma_index *a, *b, *c;
221 expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
222 expect(lzma_index_count(a) == 0);
223 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
224 expect(lzma_index_file_size(a)
225 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
228 expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
229 expect(lzma_index_count(a) == 0);
230 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
231 expect(lzma_index_file_size(a)
232 == 3 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
236 expect(lzma_index_cat(b, c, NULL, 4) == LZMA_OK);
237 expect(lzma_index_count(b) == 0);
238 expect(lzma_index_stream_size(b) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
239 expect(lzma_index_file_size(b)
240 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4);
242 expect(lzma_index_cat(a, b, NULL, 8) == 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 == 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8);
248 lzma_index_end(a, NULL);
252 lzma_vli stream_size = lzma_index_stream_size(a);
254 expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK);
255 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
256 expect(lzma_index_stream_size(a) > stream_size);
257 expect(lzma_index_stream_size(a) < stream_size * 2);
261 expect(lzma_index_cat(b, c, NULL, 8) == LZMA_OK);
262 expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK);
263 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
265 lzma_index_end(a, NULL);
269 stream_size = lzma_index_stream_size(a);
271 expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK);
272 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
273 expect(lzma_index_stream_size(a) > stream_size);
274 expect(lzma_index_stream_size(a) < stream_size * 2);
278 expect(lzma_index_cat(b, c, NULL, 8) == LZMA_OK);
279 expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK);
280 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
282 lzma_index_end(a, NULL);
290 lzma_index *i = lzma_index_init(NULL, NULL);
293 // Cannot locate anything from an empty Index.
294 expect(lzma_index_locate(i, &r, 0));
295 expect(lzma_index_locate(i, &r, 555));
297 // One empty Record: nothing is found since there's no uncompressed
299 expect(lzma_index_append(i, NULL, 16, 0) == LZMA_OK);
300 expect(lzma_index_locate(i, &r, 0));
302 // Non-empty Record and we can find something.
303 expect(lzma_index_append(i, NULL, 32, 5) == LZMA_OK);
304 expect(!lzma_index_locate(i, &r, 0));
305 expect(r.total_size == 32);
306 expect(r.uncompressed_size == 5);
307 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
308 expect(r.uncompressed_offset == 0);
310 // Still cannot find anything past the end.
311 expect(lzma_index_locate(i, &r, 5));
313 // Add the third Record.
314 expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK);
316 expect(!lzma_index_locate(i, &r, 0));
317 expect(r.total_size == 32);
318 expect(r.uncompressed_size == 5);
319 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
320 expect(r.uncompressed_offset == 0);
322 expect(!lzma_index_read(i, &r));
323 expect(r.total_size == 40);
324 expect(r.uncompressed_size == 11);
325 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
326 expect(r.uncompressed_offset == 5);
328 expect(!lzma_index_locate(i, &r, 2));
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 expect(!lzma_index_locate(i, &r, 5));
335 expect(r.total_size == 40);
336 expect(r.uncompressed_size == 11);
337 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
338 expect(r.uncompressed_offset == 5);
340 expect(!lzma_index_locate(i, &r, 5 + 11 - 1));
341 expect(r.total_size == 40);
342 expect(r.uncompressed_size == 11);
343 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
344 expect(r.uncompressed_offset == 5);
346 expect(lzma_index_locate(i, &r, 5 + 11));
347 expect(lzma_index_locate(i, &r, 5 + 15));
350 i = lzma_index_init(i, NULL);
353 for (size_t n = 4; n <= 4 * 5555; n += 4)
354 expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK);
356 expect(lzma_index_count(i) == 5555);
359 expect(!lzma_index_locate(i, &r, 0));
360 expect(r.total_size == 4 + 8);
361 expect(r.uncompressed_size == 4);
362 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE);
363 expect(r.uncompressed_offset == 0);
365 expect(!lzma_index_locate(i, &r, 3));
366 expect(r.total_size == 4 + 8);
367 expect(r.uncompressed_size == 4);
368 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE);
369 expect(r.uncompressed_offset == 0);
372 expect(!lzma_index_locate(i, &r, 4));
373 expect(r.total_size == 2 * 4 + 8);
374 expect(r.uncompressed_size == 2 * 4);
375 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 4 + 8);
376 expect(r.uncompressed_offset == 4);
379 expect(!lzma_index_locate(i, &r, lzma_index_uncompressed_size(i) - 1));
380 expect(r.total_size == 4 * 5555 + 8);
381 expect(r.uncompressed_size == 4 * 5555);
382 expect(r.stream_offset == lzma_index_total_size(i)
383 + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
384 expect(r.uncompressed_offset
385 == lzma_index_uncompressed_size(i) - 4 * 5555);
387 // Allocation chunk boundaries. See INDEX_GROUP_SIZE in
388 // liblzma/common/index.c.
389 const size_t group_multiple = 256 * 4;
390 const size_t radius = 8;
391 const size_t start = group_multiple - radius;
395 for (n = 1; n < start; ++n) {
400 while (n < start + 2 * radius) {
401 expect(!lzma_index_locate(i, &r, ubase + n * 4));
403 expect(r.stream_offset == tbase + n * 4 + 8
404 + LZMA_STREAM_HEADER_SIZE);
405 expect(r.uncompressed_offset == ubase + n * 4);
411 expect(r.total_size == n * 4 + 8);
412 expect(r.uncompressed_size == n * 4);
415 // Do it also backwards since lzma_index_locate() uses relative search.
417 expect(!lzma_index_locate(i, &r, ubase + (n - 1) * 4));
419 expect(r.total_size == n * 4 + 8);
420 expect(r.uncompressed_size == n * 4);
426 expect(r.stream_offset == tbase + n * 4 + 8
427 + LZMA_STREAM_HEADER_SIZE);
428 expect(r.uncompressed_offset == ubase + n * 4);
431 // Test locating in concatend Index.
432 i = lzma_index_init(i, NULL);
434 for (n = 0; n < group_multiple; ++n)
435 expect(lzma_index_append(i, NULL, 8, 0) == LZMA_OK);
436 expect(lzma_index_append(i, NULL, 16, 1) == LZMA_OK);
437 expect(!lzma_index_locate(i, &r, 0));
438 expect(r.total_size == 16);
439 expect(r.uncompressed_size == 1);
440 expect(r.stream_offset
441 == LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
442 expect(r.uncompressed_offset == 0);
444 lzma_index_end(i, NULL);
451 const size_t alloc_size = 128 * 1024;
452 uint8_t *buf = malloc(alloc_size);
454 lzma_stream strm = LZMA_STREAM_INIT;
456 lzma_index *i = create_empty();
457 expect(lzma_index_append(i, NULL, 0, 1) == LZMA_PROG_ERROR);
458 lzma_index_end(i, NULL);
460 // Create a valid Index and corrupt it in different ways.
462 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
463 succeed(coder_loop(&strm, NULL, 0, buf, 20,
464 LZMA_STREAM_END, LZMA_RUN));
465 lzma_index_end(i, NULL);
467 // Wrong Index Indicator
469 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
470 succeed(decoder_loop_ret(&strm, buf, 1, LZMA_DATA_ERROR));
473 // Wrong Number of Records and thus CRC32 fails.
475 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
476 succeed(decoder_loop_ret(&strm, buf, 10, LZMA_DATA_ERROR));
481 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
482 succeed(decoder_loop_ret(&strm, buf, 16, LZMA_DATA_ERROR));
496 lzma_index *i = create_empty();
498 lzma_index_end(i, NULL);
502 lzma_index_end(i, NULL);
506 lzma_index_end(i, NULL);