]> icculus.org git repositories - icculus/xz.git/blob - tests/test_index.c
Windows: Update common_w32res.rc.
[icculus/xz.git] / tests / test_index.c
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.
10 //
11 ///////////////////////////////////////////////////////////////////////////////
12
13 #include "tests.h"
14
15 #define MEMLIMIT (LZMA_VLI_C(1) << 20)
16
17 #define SMALL_COUNT 3
18 #define BIG_COUNT 5555
19
20
21 static lzma_index *
22 create_empty(void)
23 {
24         lzma_index *i = lzma_index_init(NULL);
25         expect(i != NULL);
26         return i;
27 }
28
29
30 static lzma_index *
31 create_small(void)
32 {
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;
39 }
40
41
42 static lzma_index *
43 create_big(void)
44 {
45         lzma_index *i = lzma_index_init(NULL);
46         expect(i != NULL);
47
48         lzma_vli total_size = 0;
49         lzma_vli uncompressed_size = 0;
50
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;
59         }
60
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));
67
68         return i;
69 }
70
71
72 static bool
73 is_equal(const lzma_index *a, const lzma_index *b)
74 {
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);
79
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);
85
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;
100
101                 if (ra.stream.block_count == 0)
102                         continue;
103
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;
122         }
123 }
124
125
126 static void
127 test_equal(void)
128 {
129         lzma_index *a = create_empty();
130         lzma_index *b = create_small();
131         lzma_index *c = create_big();
132         expect(a && b && c);
133
134         expect(is_equal(a, a));
135         expect(is_equal(b, b));
136         expect(is_equal(c, c));
137
138         expect(!is_equal(a, b));
139         expect(!is_equal(a, c));
140         expect(!is_equal(b, c));
141
142         lzma_index_end(a, NULL);
143         lzma_index_end(b, NULL);
144         lzma_index_end(c, NULL);
145 }
146
147
148 static void
149 test_overflow(void)
150 {
151         // Integer overflow tests
152         lzma_index *i = create_empty();
153
154         expect(lzma_index_append(i, NULL, LZMA_VLI_MAX - 5, 1234)
155                         == LZMA_DATA_ERROR);
156
157         // TODO
158
159         lzma_index_end(i, NULL);
160 }
161
162
163 static void
164 test_copy(const lzma_index *i)
165 {
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);
170 }
171
172
173 static void
174 test_read(lzma_index *i)
175 {
176         lzma_index_iter r;
177         lzma_index_iter_init(&r, i);
178
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;
186
187                 while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)) {
188                         ++count;
189
190                         total_size += r.block.total_size;
191                         uncompressed_size += r.block.uncompressed_size;
192
193                         expect(r.block.compressed_file_offset
194                                         == stream_offset);
195                         expect(r.block.uncompressed_file_offset
196                                         == uncompressed_offset);
197
198                         stream_offset += r.block.total_size;
199                         uncompressed_offset += r.block.uncompressed_size;
200                 }
201
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);
205
206                 lzma_index_iter_rewind(&r);
207         }
208 }
209
210
211 static void
212 test_code(lzma_index *i)
213 {
214         const size_t alloc_size = 128 * 1024;
215         uint8_t *buf = malloc(alloc_size);
216         expect(buf != NULL);
217
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));
224
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));
230
231         expect(is_equal(i, d));
232
233         lzma_index_end(d, NULL);
234         lzma_end(&strm);
235
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);
250
251         lzma_index_hash_end(h, NULL);
252
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);
258
259         succeed(lzma_index_buffer_encode(i, buf, &buf_pos, index_size + 1));
260         expect(buf_pos == index_size + 1);
261
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);
269
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));
274
275         lzma_index_end(d, NULL);
276
277         free(buf);
278 }
279
280
281 static void
282 test_many(lzma_index *i)
283 {
284         test_copy(i);
285         test_read(i);
286         test_code(i);
287 }
288
289
290 static void
291 test_cat(void)
292 {
293         lzma_index *a, *b, *c;
294         lzma_index_iter r;
295
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));
306
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));
313
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);
322
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);
329
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);
334
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));
342
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));
352
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));
357
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);
365
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));
370
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));
375
376         lzma_index_end(a, NULL);
377
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));
387
388         lzma_index_end(a, NULL);
389
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);
399
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);
407
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));
412
413         lzma_index_end(a, NULL);
414 }
415
416
417 static void
418 test_locate(void)
419 {
420         lzma_index *i = lzma_index_init(NULL);
421         expect(i != NULL);
422         lzma_index_iter r;
423         lzma_index_iter_init(&r, i);
424
425         // Cannot locate anything from an empty Index.
426         expect(lzma_index_iter_locate(&r, 0));
427         expect(lzma_index_iter_locate(&r, 555));
428
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));
433
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);
442
443         // Still cannot find anything past the end.
444         expect(lzma_index_iter_locate(&r, 5));
445
446         // Add the third Record.
447         expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK);
448
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);
455
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);
462
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);
469
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);
476
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);
483
484         expect(lzma_index_iter_locate(&r, 5 + 11));
485         expect(lzma_index_iter_locate(&r, 5 + 15));
486
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);
492
493         for (size_t n = 4; n <= 4 * 5555; n += 4)
494                 expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK);
495
496         expect(lzma_index_block_count(i) == 5555);
497
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);
504
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);
510
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);
518
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);
528
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;
540         }
541
542         while (n < start + 2 * radius) {
543                 expect(!lzma_index_iter_locate(&r, ubase + n * 4));
544
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);
548
549                 tbase += n * 4 + 8;
550                 ubase += n * 4;
551                 ++n;
552
553                 expect(r.block.total_size == n * 4 + 8);
554                 expect(r.block.uncompressed_size == n * 4);
555         }
556
557         // Do it also backwards.
558         while (n > start) {
559                 expect(!lzma_index_iter_locate(&r, ubase + (n - 1) * 4));
560
561                 expect(r.block.total_size == n * 4 + 8);
562                 expect(r.block.uncompressed_size == n * 4);
563
564                 --n;
565                 tbase -= n * 4 + 8;
566                 ubase -= n * 4;
567
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);
571         }
572
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);
587
588         lzma_index_end(i, NULL);
589 }
590
591
592 static void
593 test_corrupt(void)
594 {
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;
599
600         lzma_index *i = create_empty();
601         expect(lzma_index_append(i, NULL, 0, 1) == LZMA_PROG_ERROR);
602         lzma_index_end(i, NULL);
603
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);
610
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;
616
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];
622
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));
627
628         lzma_end(&strm);
629         free(buf);
630 }
631
632
633 int
634 main(void)
635 {
636         test_equal();
637
638         test_overflow();
639
640         lzma_index *i = create_empty();
641         test_many(i);
642         lzma_index_end(i, NULL);
643
644         i = create_small();
645         test_many(i);
646         lzma_index_end(i, NULL);
647
648         i = create_big();
649         test_many(i);
650         lzma_index_end(i, NULL);
651
652         test_cat();
653
654         test_locate();
655
656         test_corrupt();
657
658         return 0;
659 }