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)
21 lzma_index *i = lzma_index_init(NULL, NULL);
30 lzma_index *i = lzma_index_init(NULL, NULL);
32 expect(lzma_index_append(i, NULL, 101, 555) == LZMA_OK);
33 expect(lzma_index_append(i, NULL, 602, 777) == LZMA_OK);
34 expect(lzma_index_append(i, NULL, 804, 999) == LZMA_OK);
42 lzma_index *i = lzma_index_init(NULL, NULL);
45 lzma_vli total_size = 0;
46 lzma_vli uncompressed_size = 0;
48 // Add pseudo-random sizes (but always the same size values).
49 const size_t count = 5555;
51 for (size_t j = 0; j < count; ++j) {
53 const uint32_t t = n * 3011;
54 expect(lzma_index_append(i, NULL, t, n) == LZMA_OK);
55 total_size += (t + 3) & ~LZMA_VLI_C(3);
56 uncompressed_size += n;
59 expect(lzma_index_count(i) == count);
60 expect(lzma_index_total_size(i) == total_size);
61 expect(lzma_index_uncompressed_size(i) == uncompressed_size);
62 expect(lzma_index_total_size(i) + lzma_index_size(i)
63 + 2 * LZMA_STREAM_HEADER_SIZE
64 == lzma_index_stream_size(i));
73 lzma_index *a = create_empty();
74 lzma_index *b = create_small();
75 lzma_index *c = create_big();
78 expect(lzma_index_equal(a, a));
79 expect(lzma_index_equal(b, b));
80 expect(lzma_index_equal(c, c));
82 expect(!lzma_index_equal(a, b));
83 expect(!lzma_index_equal(a, c));
84 expect(!lzma_index_equal(b, c));
86 lzma_index_end(a, NULL);
87 lzma_index_end(b, NULL);
88 lzma_index_end(c, NULL);
95 // Integer overflow tests
96 lzma_index *i = create_empty();
98 expect(lzma_index_append(i, NULL, LZMA_VLI_MAX - 5, 1234)
103 lzma_index_end(i, NULL);
108 test_copy(const lzma_index *i)
110 lzma_index *d = lzma_index_dup(i, NULL);
112 lzma_index_end(d, NULL);
117 test_read(lzma_index *i)
119 lzma_index_record record;
121 // Try twice so we see that rewinding works.
122 for (size_t j = 0; j < 2; ++j) {
123 lzma_vli total_size = 0;
124 lzma_vli uncompressed_size = 0;
125 lzma_vli stream_offset = LZMA_STREAM_HEADER_SIZE;
126 lzma_vli uncompressed_offset = 0;
129 while (!lzma_index_read(i, &record)) {
132 total_size += record.total_size;
133 uncompressed_size += record.uncompressed_size;
135 expect(record.stream_offset == stream_offset);
136 expect(record.uncompressed_offset
137 == uncompressed_offset);
139 stream_offset += record.total_size;
140 uncompressed_offset += record.uncompressed_size;
143 expect(lzma_index_total_size(i) == total_size);
144 expect(lzma_index_uncompressed_size(i) == uncompressed_size);
145 expect(lzma_index_count(i) == count);
147 lzma_index_rewind(i);
153 test_code(lzma_index *i)
155 const size_t alloc_size = 128 * 1024;
156 uint8_t *buf = malloc(alloc_size);
160 lzma_stream strm = LZMA_STREAM_INIT;
161 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
162 const lzma_vli index_size = lzma_index_size(i);
163 succeed(coder_loop(&strm, NULL, 0, buf, index_size,
164 LZMA_STREAM_END, LZMA_RUN));
168 expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK);
169 succeed(decoder_loop(&strm, buf, index_size));
171 expect(lzma_index_equal(i, d));
173 lzma_index_end(d, NULL);
176 // Decode with hashing
177 lzma_index_hash *h = lzma_index_hash_init(NULL, NULL);
179 lzma_index_rewind(i);
181 while (!lzma_index_read(i, &r))
182 expect(lzma_index_hash_append(h, r.unpadded_size,
183 r.uncompressed_size) == LZMA_OK);
185 while (pos < index_size - 1)
186 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
188 expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
191 lzma_index_hash_end(h, NULL);
195 expect(lzma_index_buffer_encode(i, buf, &buf_pos, index_size)
197 expect(buf_pos == 1);
199 succeed(lzma_index_buffer_encode(i, buf, &buf_pos, index_size + 1));
200 expect(buf_pos == index_size + 1);
204 uint64_t memlimit = MEMLIMIT;
205 expect(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
206 index_size) == LZMA_DATA_ERROR);
207 expect(buf_pos == 1);
210 succeed(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
212 expect(buf_pos == index_size + 1);
213 expect(lzma_index_equal(i, d));
215 lzma_index_end(d, NULL);
222 test_many(lzma_index *i)
233 lzma_index *a, *b, *c;
238 expect(lzma_index_cat(a, b, NULL, 0) == LZMA_OK);
239 expect(lzma_index_count(a) == 0);
240 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
241 expect(lzma_index_file_size(a)
242 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
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 == 3 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
253 expect(lzma_index_cat(b, c, NULL, 4) == LZMA_OK);
254 expect(lzma_index_count(b) == 0);
255 expect(lzma_index_stream_size(b) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
256 expect(lzma_index_file_size(b)
257 == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4);
259 expect(lzma_index_cat(a, b, NULL, 8) == LZMA_OK);
260 expect(lzma_index_count(a) == 0);
261 expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
262 expect(lzma_index_file_size(a)
263 == 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8);
265 lzma_index_end(a, NULL);
269 lzma_vli 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);
286 stream_size = lzma_index_stream_size(a);
288 expect(lzma_index_cat(a, b, NULL, 4) == LZMA_OK);
289 expect(lzma_index_file_size(a) == stream_size * 2 + 4);
290 expect(lzma_index_stream_size(a) > stream_size);
291 expect(lzma_index_stream_size(a) < stream_size * 2);
295 expect(lzma_index_cat(b, c, NULL, 8) == LZMA_OK);
296 expect(lzma_index_cat(a, b, NULL, 12) == LZMA_OK);
297 expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
299 lzma_index_end(a, NULL);
307 lzma_index *i = lzma_index_init(NULL, NULL);
310 // Cannot locate anything from an empty Index.
311 expect(lzma_index_locate(i, &r, 0));
312 expect(lzma_index_locate(i, &r, 555));
314 // One empty Record: nothing is found since there's no uncompressed
316 expect(lzma_index_append(i, NULL, 16, 0) == LZMA_OK);
317 expect(lzma_index_locate(i, &r, 0));
319 // Non-empty Record and we can find something.
320 expect(lzma_index_append(i, NULL, 32, 5) == LZMA_OK);
321 expect(!lzma_index_locate(i, &r, 0));
322 expect(r.total_size == 32);
323 expect(r.uncompressed_size == 5);
324 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
325 expect(r.uncompressed_offset == 0);
327 // Still cannot find anything past the end.
328 expect(lzma_index_locate(i, &r, 5));
330 // Add the third Record.
331 expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK);
333 expect(!lzma_index_locate(i, &r, 0));
334 expect(r.total_size == 32);
335 expect(r.uncompressed_size == 5);
336 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16);
337 expect(r.uncompressed_offset == 0);
339 expect(!lzma_index_read(i, &r));
340 expect(r.total_size == 40);
341 expect(r.uncompressed_size == 11);
342 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
343 expect(r.uncompressed_offset == 5);
345 expect(!lzma_index_locate(i, &r, 2));
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 expect(!lzma_index_locate(i, &r, 5));
352 expect(r.total_size == 40);
353 expect(r.uncompressed_size == 11);
354 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
355 expect(r.uncompressed_offset == 5);
357 expect(!lzma_index_locate(i, &r, 5 + 11 - 1));
358 expect(r.total_size == 40);
359 expect(r.uncompressed_size == 11);
360 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 16 + 32);
361 expect(r.uncompressed_offset == 5);
363 expect(lzma_index_locate(i, &r, 5 + 11));
364 expect(lzma_index_locate(i, &r, 5 + 15));
367 i = lzma_index_init(i, NULL);
370 for (size_t n = 4; n <= 4 * 5555; n += 4)
371 expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK);
373 expect(lzma_index_count(i) == 5555);
376 expect(!lzma_index_locate(i, &r, 0));
377 expect(r.total_size == 4 + 8);
378 expect(r.uncompressed_size == 4);
379 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE);
380 expect(r.uncompressed_offset == 0);
382 expect(!lzma_index_locate(i, &r, 3));
383 expect(r.total_size == 4 + 8);
384 expect(r.uncompressed_size == 4);
385 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE);
386 expect(r.uncompressed_offset == 0);
389 expect(!lzma_index_locate(i, &r, 4));
390 expect(r.total_size == 2 * 4 + 8);
391 expect(r.uncompressed_size == 2 * 4);
392 expect(r.stream_offset == LZMA_STREAM_HEADER_SIZE + 4 + 8);
393 expect(r.uncompressed_offset == 4);
396 expect(!lzma_index_locate(i, &r, lzma_index_uncompressed_size(i) - 1));
397 expect(r.total_size == 4 * 5555 + 8);
398 expect(r.uncompressed_size == 4 * 5555);
399 expect(r.stream_offset == lzma_index_total_size(i)
400 + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
401 expect(r.uncompressed_offset
402 == lzma_index_uncompressed_size(i) - 4 * 5555);
404 // Allocation chunk boundaries. See INDEX_GROUP_SIZE in
405 // liblzma/common/index.c.
406 const size_t group_multiple = 256 * 4;
407 const size_t radius = 8;
408 const size_t start = group_multiple - radius;
412 for (n = 1; n < start; ++n) {
417 while (n < start + 2 * radius) {
418 expect(!lzma_index_locate(i, &r, ubase + n * 4));
420 expect(r.stream_offset == tbase + n * 4 + 8
421 + LZMA_STREAM_HEADER_SIZE);
422 expect(r.uncompressed_offset == ubase + n * 4);
428 expect(r.total_size == n * 4 + 8);
429 expect(r.uncompressed_size == n * 4);
432 // Do it also backwards since lzma_index_locate() uses relative search.
434 expect(!lzma_index_locate(i, &r, ubase + (n - 1) * 4));
436 expect(r.total_size == n * 4 + 8);
437 expect(r.uncompressed_size == n * 4);
443 expect(r.stream_offset == tbase + n * 4 + 8
444 + LZMA_STREAM_HEADER_SIZE);
445 expect(r.uncompressed_offset == ubase + n * 4);
448 // Test locating in concatend Index.
449 i = lzma_index_init(i, NULL);
451 for (n = 0; n < group_multiple; ++n)
452 expect(lzma_index_append(i, NULL, 8, 0) == LZMA_OK);
453 expect(lzma_index_append(i, NULL, 16, 1) == LZMA_OK);
454 expect(!lzma_index_locate(i, &r, 0));
455 expect(r.total_size == 16);
456 expect(r.uncompressed_size == 1);
457 expect(r.stream_offset
458 == LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
459 expect(r.uncompressed_offset == 0);
461 lzma_index_end(i, NULL);
468 const size_t alloc_size = 128 * 1024;
469 uint8_t *buf = malloc(alloc_size);
471 lzma_stream strm = LZMA_STREAM_INIT;
473 lzma_index *i = create_empty();
474 expect(lzma_index_append(i, NULL, 0, 1) == LZMA_PROG_ERROR);
475 lzma_index_end(i, NULL);
477 // Create a valid Index and corrupt it in different ways.
479 expect(lzma_index_encoder(&strm, i) == LZMA_OK);
480 succeed(coder_loop(&strm, NULL, 0, buf, 20,
481 LZMA_STREAM_END, LZMA_RUN));
482 lzma_index_end(i, NULL);
484 // Wrong Index Indicator
486 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
487 succeed(decoder_loop_ret(&strm, buf, 1, LZMA_DATA_ERROR));
490 // Wrong Number of Records and thus CRC32 fails.
492 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
493 succeed(decoder_loop_ret(&strm, buf, 10, LZMA_DATA_ERROR));
498 expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
499 succeed(decoder_loop_ret(&strm, buf, 16, LZMA_DATA_ERROR));
513 lzma_index *i = create_empty();
515 lzma_index_end(i, NULL);
519 lzma_index_end(i, NULL);
523 lzma_index_end(i, NULL);