Home | History | Annotate | Line # | Download | only in tests
      1      1.1  joerg ///////////////////////////////////////////////////////////////////////////////
      2      1.1  joerg //
      3      1.1  joerg /// \file       test_index.c
      4      1.1  joerg /// \brief      Tests functions handling the lzma_index structure
      5      1.1  joerg //
      6      1.1  joerg //  Author:     Lasse Collin
      7      1.1  joerg //
      8      1.1  joerg //  This file has been put into the public domain.
      9      1.1  joerg //  You can do whatever you want with this file.
     10      1.1  joerg //
     11      1.1  joerg ///////////////////////////////////////////////////////////////////////////////
     12      1.1  joerg 
     13      1.1  joerg #include "tests.h"
     14      1.1  joerg 
     15      1.1  joerg #define MEMLIMIT (LZMA_VLI_C(1) << 20)
     16      1.1  joerg 
     17      1.1  joerg #define SMALL_COUNT 3
     18      1.1  joerg #define BIG_COUNT 5555
     19      1.1  joerg 
     20      1.1  joerg 
     21      1.1  joerg static lzma_index *
     22      1.1  joerg create_empty(void)
     23      1.1  joerg {
     24      1.1  joerg 	lzma_index *i = lzma_index_init(NULL);
     25      1.1  joerg 	expect(i != NULL);
     26      1.1  joerg 	return i;
     27      1.1  joerg }
     28      1.1  joerg 
     29      1.1  joerg 
     30      1.1  joerg static lzma_index *
     31      1.1  joerg create_small(void)
     32      1.1  joerg {
     33      1.1  joerg 	lzma_index *i = lzma_index_init(NULL);
     34      1.1  joerg 	expect(i != NULL);
     35      1.1  joerg 	expect(lzma_index_append(i, NULL, 101, 555) == LZMA_OK);
     36      1.1  joerg 	expect(lzma_index_append(i, NULL, 602, 777) == LZMA_OK);
     37      1.1  joerg 	expect(lzma_index_append(i, NULL, 804, 999) == LZMA_OK);
     38      1.1  joerg 	return i;
     39      1.1  joerg }
     40      1.1  joerg 
     41      1.1  joerg 
     42      1.1  joerg static lzma_index *
     43      1.1  joerg create_big(void)
     44      1.1  joerg {
     45      1.1  joerg 	lzma_index *i = lzma_index_init(NULL);
     46      1.1  joerg 	expect(i != NULL);
     47      1.1  joerg 
     48      1.1  joerg 	lzma_vli total_size = 0;
     49      1.1  joerg 	lzma_vli uncompressed_size = 0;
     50      1.1  joerg 
     51      1.1  joerg 	// Add pseudo-random sizes (but always the same size values).
     52      1.1  joerg 	uint32_t n = 11;
     53      1.1  joerg 	for (size_t j = 0; j < BIG_COUNT; ++j) {
     54      1.1  joerg 		n = 7019 * n + 7607;
     55      1.1  joerg 		const uint32_t t = n * 3011;
     56      1.1  joerg 		expect(lzma_index_append(i, NULL, t, n) == LZMA_OK);
     57      1.1  joerg 		total_size += (t + 3) & ~LZMA_VLI_C(3);
     58      1.1  joerg 		uncompressed_size += n;
     59      1.1  joerg 	}
     60      1.1  joerg 
     61      1.1  joerg 	expect(lzma_index_block_count(i) == BIG_COUNT);
     62      1.1  joerg 	expect(lzma_index_total_size(i) == total_size);
     63      1.1  joerg 	expect(lzma_index_uncompressed_size(i) == uncompressed_size);
     64      1.1  joerg 	expect(lzma_index_total_size(i) + lzma_index_size(i)
     65      1.1  joerg 				+ 2 * LZMA_STREAM_HEADER_SIZE
     66      1.1  joerg 			== lzma_index_stream_size(i));
     67      1.1  joerg 
     68      1.1  joerg 	return i;
     69      1.1  joerg }
     70      1.1  joerg 
     71      1.1  joerg 
     72      1.1  joerg static bool
     73      1.1  joerg is_equal(const lzma_index *a, const lzma_index *b)
     74      1.1  joerg {
     75      1.1  joerg 	// Compare only the Stream and Block sizes and offsets.
     76      1.1  joerg 	lzma_index_iter ra, rb;
     77      1.1  joerg 	lzma_index_iter_init(&ra, a);
     78      1.1  joerg 	lzma_index_iter_init(&rb, b);
     79      1.1  joerg 
     80      1.1  joerg 	while (true) {
     81      1.1  joerg 		bool reta = lzma_index_iter_next(&ra, LZMA_INDEX_ITER_ANY);
     82      1.1  joerg 		bool retb = lzma_index_iter_next(&rb, LZMA_INDEX_ITER_ANY);
     83      1.1  joerg 		if (reta)
     84      1.1  joerg 			return !(reta ^ retb);
     85      1.1  joerg 
     86      1.1  joerg 		if (ra.stream.number != rb.stream.number
     87      1.1  joerg 				|| ra.stream.block_count
     88      1.1  joerg 					!= rb.stream.block_count
     89      1.1  joerg 				|| ra.stream.compressed_offset
     90      1.1  joerg 					!= rb.stream.compressed_offset
     91      1.1  joerg 				|| ra.stream.uncompressed_offset
     92      1.1  joerg 					!= rb.stream.uncompressed_offset
     93      1.1  joerg 				|| ra.stream.compressed_size
     94      1.1  joerg 					!= rb.stream.compressed_size
     95      1.1  joerg 				|| ra.stream.uncompressed_size
     96      1.1  joerg 					!= rb.stream.uncompressed_size
     97      1.1  joerg 				|| ra.stream.padding
     98      1.1  joerg 					!= rb.stream.padding)
     99      1.1  joerg 			return false;
    100      1.1  joerg 
    101      1.1  joerg 		if (ra.stream.block_count == 0)
    102      1.1  joerg 			continue;
    103      1.1  joerg 
    104      1.1  joerg 		if (ra.block.number_in_file != rb.block.number_in_file
    105      1.1  joerg 				|| ra.block.compressed_file_offset
    106      1.1  joerg 					!= rb.block.compressed_file_offset
    107      1.1  joerg 				|| ra.block.uncompressed_file_offset
    108      1.1  joerg 					!= rb.block.uncompressed_file_offset
    109      1.1  joerg 				|| ra.block.number_in_stream
    110      1.1  joerg 					!= rb.block.number_in_stream
    111      1.1  joerg 				|| ra.block.compressed_stream_offset
    112      1.1  joerg 					!= rb.block.compressed_stream_offset
    113      1.1  joerg 				|| ra.block.uncompressed_stream_offset
    114      1.1  joerg 					!= rb.block.uncompressed_stream_offset
    115      1.1  joerg 				|| ra.block.uncompressed_size
    116      1.1  joerg 					!= rb.block.uncompressed_size
    117      1.1  joerg 				|| ra.block.unpadded_size
    118      1.1  joerg 					!= rb.block.unpadded_size
    119      1.1  joerg 				|| ra.block.total_size
    120      1.1  joerg 					!= rb.block.total_size)
    121      1.1  joerg 			return false;
    122      1.1  joerg 	}
    123      1.1  joerg }
    124      1.1  joerg 
    125      1.1  joerg 
    126      1.1  joerg static void
    127      1.1  joerg test_equal(void)
    128      1.1  joerg {
    129      1.1  joerg 	lzma_index *a = create_empty();
    130      1.1  joerg 	lzma_index *b = create_small();
    131      1.1  joerg 	lzma_index *c = create_big();
    132      1.1  joerg 	expect(a && b && c);
    133      1.1  joerg 
    134      1.1  joerg 	expect(is_equal(a, a));
    135      1.1  joerg 	expect(is_equal(b, b));
    136      1.1  joerg 	expect(is_equal(c, c));
    137      1.1  joerg 
    138      1.1  joerg 	expect(!is_equal(a, b));
    139      1.1  joerg 	expect(!is_equal(a, c));
    140      1.1  joerg 	expect(!is_equal(b, c));
    141      1.1  joerg 
    142      1.1  joerg 	lzma_index_end(a, NULL);
    143      1.1  joerg 	lzma_index_end(b, NULL);
    144      1.1  joerg 	lzma_index_end(c, NULL);
    145      1.1  joerg }
    146      1.1  joerg 
    147      1.1  joerg 
    148      1.1  joerg static void
    149      1.1  joerg test_overflow(void)
    150      1.1  joerg {
    151      1.1  joerg 	// Integer overflow tests
    152      1.1  joerg 	lzma_index *i = create_empty();
    153      1.1  joerg 
    154      1.1  joerg 	expect(lzma_index_append(i, NULL, LZMA_VLI_MAX - 5, 1234)
    155      1.1  joerg 			== LZMA_DATA_ERROR);
    156      1.1  joerg 
    157      1.1  joerg 	// TODO
    158      1.1  joerg 
    159      1.1  joerg 	lzma_index_end(i, NULL);
    160      1.1  joerg }
    161      1.1  joerg 
    162      1.1  joerg 
    163      1.1  joerg static void
    164      1.1  joerg test_copy(const lzma_index *i)
    165      1.1  joerg {
    166      1.1  joerg 	lzma_index *d = lzma_index_dup(i, NULL);
    167      1.1  joerg 	expect(d != NULL);
    168      1.1  joerg 	expect(is_equal(i, d));
    169      1.1  joerg 	lzma_index_end(d, NULL);
    170      1.1  joerg }
    171      1.1  joerg 
    172      1.1  joerg 
    173      1.1  joerg static void
    174      1.1  joerg test_read(lzma_index *i)
    175      1.1  joerg {
    176      1.1  joerg 	lzma_index_iter r;
    177      1.1  joerg 	lzma_index_iter_init(&r, i);
    178      1.1  joerg 
    179      1.1  joerg 	// Try twice so we see that rewinding works.
    180      1.1  joerg 	for (size_t j = 0; j < 2; ++j) {
    181      1.1  joerg 		lzma_vli total_size = 0;
    182      1.1  joerg 		lzma_vli uncompressed_size = 0;
    183      1.1  joerg 		lzma_vli stream_offset = LZMA_STREAM_HEADER_SIZE;
    184      1.1  joerg 		lzma_vli uncompressed_offset = 0;
    185      1.1  joerg 		uint32_t count = 0;
    186      1.1  joerg 
    187      1.1  joerg 		while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)) {
    188      1.1  joerg 			++count;
    189      1.1  joerg 
    190      1.1  joerg 			total_size += r.block.total_size;
    191      1.1  joerg 			uncompressed_size += r.block.uncompressed_size;
    192      1.1  joerg 
    193      1.1  joerg 			expect(r.block.compressed_file_offset
    194      1.1  joerg 					== stream_offset);
    195      1.1  joerg 			expect(r.block.uncompressed_file_offset
    196      1.1  joerg 					== uncompressed_offset);
    197      1.1  joerg 
    198      1.1  joerg 			stream_offset += r.block.total_size;
    199      1.1  joerg 			uncompressed_offset += r.block.uncompressed_size;
    200      1.1  joerg 		}
    201      1.1  joerg 
    202      1.1  joerg 		expect(lzma_index_total_size(i) == total_size);
    203      1.1  joerg 		expect(lzma_index_uncompressed_size(i) == uncompressed_size);
    204      1.1  joerg 		expect(lzma_index_block_count(i) == count);
    205      1.1  joerg 
    206      1.1  joerg 		lzma_index_iter_rewind(&r);
    207      1.1  joerg 	}
    208      1.1  joerg }
    209      1.1  joerg 
    210      1.1  joerg 
    211      1.1  joerg static void
    212      1.1  joerg test_code(lzma_index *i)
    213      1.1  joerg {
    214      1.1  joerg 	const size_t alloc_size = 128 * 1024;
    215      1.1  joerg 	uint8_t *buf = malloc(alloc_size);
    216      1.1  joerg 	expect(buf != NULL);
    217      1.1  joerg 
    218      1.1  joerg 	// Encode
    219      1.1  joerg 	lzma_stream strm = LZMA_STREAM_INIT;
    220      1.1  joerg 	expect(lzma_index_encoder(&strm, i) == LZMA_OK);
    221      1.1  joerg 	const lzma_vli index_size = lzma_index_size(i);
    222      1.1  joerg 	succeed(coder_loop(&strm, NULL, 0, buf, index_size,
    223      1.1  joerg 			LZMA_STREAM_END, LZMA_RUN));
    224      1.1  joerg 
    225      1.1  joerg 	// Decode
    226      1.1  joerg 	lzma_index *d;
    227      1.1  joerg 	expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK);
    228      1.1  joerg 	expect(d == NULL);
    229      1.1  joerg 	succeed(decoder_loop(&strm, buf, index_size));
    230      1.1  joerg 
    231      1.1  joerg 	expect(is_equal(i, d));
    232      1.1  joerg 
    233      1.1  joerg 	lzma_index_end(d, NULL);
    234      1.1  joerg 	lzma_end(&strm);
    235      1.1  joerg 
    236      1.1  joerg 	// Decode with hashing
    237      1.1  joerg 	lzma_index_hash *h = lzma_index_hash_init(NULL, NULL);
    238      1.1  joerg 	expect(h != NULL);
    239      1.1  joerg 	lzma_index_iter r;
    240      1.1  joerg 	lzma_index_iter_init(&r, i);
    241      1.1  joerg 	while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK))
    242      1.1  joerg 		expect(lzma_index_hash_append(h, r.block.unpadded_size,
    243      1.1  joerg 				r.block.uncompressed_size) == LZMA_OK);
    244      1.1  joerg 	size_t pos = 0;
    245      1.1  joerg 	while (pos < index_size - 1)
    246      1.1  joerg 		expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
    247      1.1  joerg 				== LZMA_OK);
    248      1.1  joerg 	expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
    249      1.1  joerg 			== LZMA_STREAM_END);
    250      1.1  joerg 
    251      1.1  joerg 	lzma_index_hash_end(h, NULL);
    252      1.1  joerg 
    253      1.1  joerg 	// Encode buffer
    254      1.1  joerg 	size_t buf_pos = 1;
    255      1.1  joerg 	expect(lzma_index_buffer_encode(i, buf, &buf_pos, index_size)
    256      1.1  joerg 			== LZMA_BUF_ERROR);
    257      1.1  joerg 	expect(buf_pos == 1);
    258      1.1  joerg 
    259      1.1  joerg 	succeed(lzma_index_buffer_encode(i, buf, &buf_pos, index_size + 1));
    260      1.1  joerg 	expect(buf_pos == index_size + 1);
    261      1.1  joerg 
    262      1.1  joerg 	// Decode buffer
    263      1.1  joerg 	buf_pos = 1;
    264      1.1  joerg 	uint64_t memlimit = MEMLIMIT;
    265      1.1  joerg 	expect(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
    266      1.1  joerg 			index_size) == LZMA_DATA_ERROR);
    267      1.1  joerg 	expect(buf_pos == 1);
    268      1.1  joerg 	expect(d == NULL);
    269      1.1  joerg 
    270      1.1  joerg 	succeed(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
    271      1.1  joerg 			index_size + 1));
    272      1.1  joerg 	expect(buf_pos == index_size + 1);
    273      1.1  joerg 	expect(is_equal(i, d));
    274      1.1  joerg 
    275      1.1  joerg 	lzma_index_end(d, NULL);
    276      1.1  joerg 
    277      1.1  joerg 	free(buf);
    278      1.1  joerg }
    279      1.1  joerg 
    280      1.1  joerg 
    281      1.1  joerg static void
    282      1.1  joerg test_many(lzma_index *i)
    283      1.1  joerg {
    284      1.1  joerg 	test_copy(i);
    285      1.1  joerg 	test_read(i);
    286      1.1  joerg 	test_code(i);
    287      1.1  joerg }
    288      1.1  joerg 
    289      1.1  joerg 
    290      1.1  joerg static void
    291      1.1  joerg test_cat(void)
    292      1.1  joerg {
    293      1.1  joerg 	lzma_index *a, *b, *c;
    294      1.1  joerg 	lzma_index_iter r;
    295      1.1  joerg 
    296      1.1  joerg 	// Empty Indexes
    297      1.1  joerg 	a = create_empty();
    298      1.1  joerg 	b = create_empty();
    299      1.1  joerg 	expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    300      1.1  joerg 	expect(lzma_index_block_count(a) == 0);
    301      1.1  joerg 	expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
    302      1.1  joerg 	expect(lzma_index_file_size(a)
    303      1.1  joerg 			== 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
    304      1.1  joerg 	lzma_index_iter_init(&r, a);
    305      1.1  joerg 	expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
    306      1.1  joerg 
    307      1.1  joerg 	b = create_empty();
    308      1.1  joerg 	expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    309      1.1  joerg 	expect(lzma_index_block_count(a) == 0);
    310      1.1  joerg 	expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
    311      1.1  joerg 	expect(lzma_index_file_size(a)
    312      1.1  joerg 			== 3 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
    313      1.1  joerg 
    314      1.1  joerg 	b = create_empty();
    315      1.1  joerg 	c = create_empty();
    316      1.1  joerg 	expect(lzma_index_stream_padding(b, 4) == LZMA_OK);
    317      1.1  joerg 	expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
    318      1.1  joerg 	expect(lzma_index_block_count(b) == 0);
    319      1.1  joerg 	expect(lzma_index_stream_size(b) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
    320      1.1  joerg 	expect(lzma_index_file_size(b)
    321      1.1  joerg 			== 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4);
    322      1.1  joerg 
    323      1.1  joerg 	expect(lzma_index_stream_padding(a, 8) == LZMA_OK);
    324      1.1  joerg 	expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    325      1.1  joerg 	expect(lzma_index_block_count(a) == 0);
    326      1.1  joerg 	expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
    327      1.1  joerg 	expect(lzma_index_file_size(a)
    328      1.1  joerg 			== 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8);
    329      1.1  joerg 
    330      1.1  joerg 	expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
    331      1.1  joerg 	lzma_index_iter_rewind(&r);
    332      1.1  joerg 	expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
    333      1.1  joerg 	lzma_index_end(a, NULL);
    334      1.1  joerg 
    335      1.1  joerg 	// Small Indexes
    336      1.1  joerg 	a = create_small();
    337      1.1  joerg 	lzma_vli stream_size = lzma_index_stream_size(a);
    338      1.1  joerg 	lzma_index_iter_init(&r, a);
    339      1.1  joerg 	for (int i = SMALL_COUNT; i >= 0; --i)
    340      1.1  joerg 		expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
    341      1.1  joerg 				^ (i == 0));
    342      1.1  joerg 
    343      1.1  joerg 	b = create_small();
    344      1.1  joerg 	expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
    345      1.1  joerg 	expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    346      1.1  joerg 	expect(lzma_index_file_size(a) == stream_size * 2 + 4);
    347      1.1  joerg 	expect(lzma_index_stream_size(a) > stream_size);
    348      1.1  joerg 	expect(lzma_index_stream_size(a) < stream_size * 2);
    349      1.1  joerg 	for (int i = SMALL_COUNT; i >= 0; --i)
    350      1.1  joerg 		expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
    351      1.1  joerg 				^ (i == 0));
    352      1.1  joerg 
    353      1.1  joerg 	lzma_index_iter_rewind(&r);
    354      1.1  joerg 	for (int i = SMALL_COUNT * 2; i >= 0; --i)
    355      1.1  joerg 		expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
    356      1.1  joerg 				^ (i == 0));
    357      1.1  joerg 
    358      1.1  joerg 	b = create_small();
    359      1.1  joerg 	c = create_small();
    360      1.1  joerg 	expect(lzma_index_stream_padding(b, 8) == LZMA_OK);
    361      1.1  joerg 	expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
    362      1.1  joerg 	expect(lzma_index_stream_padding(a, 12) == LZMA_OK);
    363      1.1  joerg 	expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    364      1.1  joerg 	expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
    365      1.1  joerg 
    366      1.1  joerg 	expect(lzma_index_block_count(a) == SMALL_COUNT * 4);
    367      1.1  joerg 	for (int i = SMALL_COUNT * 2; i >= 0; --i)
    368      1.1  joerg 		expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
    369      1.1  joerg 				^ (i == 0));
    370      1.1  joerg 
    371      1.1  joerg 	lzma_index_iter_rewind(&r);
    372      1.1  joerg 	for (int i = SMALL_COUNT * 4; i >= 0; --i)
    373      1.1  joerg 		expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
    374      1.1  joerg 				^ (i == 0));
    375      1.1  joerg 
    376      1.1  joerg 	lzma_index_end(a, NULL);
    377      1.1  joerg 
    378      1.1  joerg 	// Mix of empty and small
    379      1.1  joerg 	a = create_empty();
    380      1.1  joerg 	b = create_small();
    381      1.1  joerg 	expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
    382      1.1  joerg 	expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    383      1.1  joerg 	lzma_index_iter_init(&r, a);
    384      1.1  joerg 	for (int i = SMALL_COUNT; i >= 0; --i)
    385      1.1  joerg 		expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
    386      1.1  joerg 				^ (i == 0));
    387      1.1  joerg 
    388      1.1  joerg 	lzma_index_end(a, NULL);
    389      1.1  joerg 
    390      1.1  joerg 	// Big Indexes
    391      1.1  joerg 	a = create_big();
    392      1.1  joerg 	stream_size = lzma_index_stream_size(a);
    393      1.1  joerg 	b = create_big();
    394      1.1  joerg 	expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
    395      1.1  joerg 	expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    396      1.1  joerg 	expect(lzma_index_file_size(a) == stream_size * 2 + 4);
    397      1.1  joerg 	expect(lzma_index_stream_size(a) > stream_size);
    398      1.1  joerg 	expect(lzma_index_stream_size(a) < stream_size * 2);
    399      1.1  joerg 
    400      1.1  joerg 	b = create_big();
    401      1.1  joerg 	c = create_big();
    402      1.1  joerg 	expect(lzma_index_stream_padding(b, 8) == LZMA_OK);
    403      1.1  joerg 	expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
    404      1.1  joerg 	expect(lzma_index_stream_padding(a, 12) == LZMA_OK);
    405      1.1  joerg 	expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    406      1.1  joerg 	expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);
    407      1.1  joerg 
    408      1.1  joerg 	lzma_index_iter_init(&r, a);
    409      1.1  joerg 	for (int i = BIG_COUNT * 4; i >= 0; --i)
    410      1.1  joerg 		expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
    411      1.1  joerg 				^ (i == 0));
    412      1.1  joerg 
    413      1.1  joerg 	lzma_index_end(a, NULL);
    414      1.1  joerg }
    415      1.1  joerg 
    416      1.1  joerg 
    417      1.1  joerg static void
    418      1.1  joerg test_locate(void)
    419      1.1  joerg {
    420      1.1  joerg 	lzma_index *i = lzma_index_init(NULL);
    421      1.1  joerg 	expect(i != NULL);
    422      1.1  joerg 	lzma_index_iter r;
    423      1.1  joerg 	lzma_index_iter_init(&r, i);
    424      1.1  joerg 
    425      1.1  joerg 	// Cannot locate anything from an empty Index.
    426      1.1  joerg 	expect(lzma_index_iter_locate(&r, 0));
    427      1.1  joerg 	expect(lzma_index_iter_locate(&r, 555));
    428      1.1  joerg 
    429      1.1  joerg 	// One empty Record: nothing is found since there's no uncompressed
    430      1.1  joerg 	// data.
    431      1.1  joerg 	expect(lzma_index_append(i, NULL, 16, 0) == LZMA_OK);
    432      1.1  joerg 	expect(lzma_index_iter_locate(&r, 0));
    433      1.1  joerg 
    434      1.1  joerg 	// Non-empty Record and we can find something.
    435      1.1  joerg 	expect(lzma_index_append(i, NULL, 32, 5) == LZMA_OK);
    436      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 0));
    437      1.1  joerg 	expect(r.block.total_size == 32);
    438      1.1  joerg 	expect(r.block.uncompressed_size == 5);
    439      1.1  joerg 	expect(r.block.compressed_file_offset
    440      1.1  joerg 			== LZMA_STREAM_HEADER_SIZE + 16);
    441      1.1  joerg 	expect(r.block.uncompressed_file_offset == 0);
    442      1.1  joerg 
    443      1.1  joerg 	// Still cannot find anything past the end.
    444      1.1  joerg 	expect(lzma_index_iter_locate(&r, 5));
    445      1.1  joerg 
    446      1.1  joerg 	// Add the third Record.
    447      1.1  joerg 	expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK);
    448      1.1  joerg 
    449      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 0));
    450      1.1  joerg 	expect(r.block.total_size == 32);
    451      1.1  joerg 	expect(r.block.uncompressed_size == 5);
    452      1.1  joerg 	expect(r.block.compressed_file_offset
    453      1.1  joerg 			== LZMA_STREAM_HEADER_SIZE + 16);
    454      1.1  joerg 	expect(r.block.uncompressed_file_offset == 0);
    455      1.1  joerg 
    456      1.1  joerg 	expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
    457      1.1  joerg 	expect(r.block.total_size == 40);
    458      1.1  joerg 	expect(r.block.uncompressed_size == 11);
    459      1.1  joerg 	expect(r.block.compressed_file_offset
    460      1.1  joerg 			== LZMA_STREAM_HEADER_SIZE + 16 + 32);
    461      1.1  joerg 	expect(r.block.uncompressed_file_offset == 5);
    462      1.1  joerg 
    463      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 2));
    464      1.1  joerg 	expect(r.block.total_size == 32);
    465      1.1  joerg 	expect(r.block.uncompressed_size == 5);
    466      1.1  joerg 	expect(r.block.compressed_file_offset
    467      1.1  joerg 			== LZMA_STREAM_HEADER_SIZE + 16);
    468      1.1  joerg 	expect(r.block.uncompressed_file_offset == 0);
    469      1.1  joerg 
    470      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 5));
    471      1.1  joerg 	expect(r.block.total_size == 40);
    472      1.1  joerg 	expect(r.block.uncompressed_size == 11);
    473      1.1  joerg 	expect(r.block.compressed_file_offset
    474      1.1  joerg 			== LZMA_STREAM_HEADER_SIZE + 16 + 32);
    475      1.1  joerg 	expect(r.block.uncompressed_file_offset == 5);
    476      1.1  joerg 
    477      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 5 + 11 - 1));
    478      1.1  joerg 	expect(r.block.total_size == 40);
    479      1.1  joerg 	expect(r.block.uncompressed_size == 11);
    480      1.1  joerg 	expect(r.block.compressed_file_offset
    481      1.1  joerg 			== LZMA_STREAM_HEADER_SIZE + 16 + 32);
    482      1.1  joerg 	expect(r.block.uncompressed_file_offset == 5);
    483      1.1  joerg 
    484      1.1  joerg 	expect(lzma_index_iter_locate(&r, 5 + 11));
    485      1.1  joerg 	expect(lzma_index_iter_locate(&r, 5 + 15));
    486      1.1  joerg 
    487      1.1  joerg 	// Large Index
    488      1.1  joerg 	lzma_index_end(i, NULL);
    489      1.1  joerg 	i = lzma_index_init(NULL);
    490      1.1  joerg 	expect(i != NULL);
    491      1.1  joerg 	lzma_index_iter_init(&r, i);
    492      1.1  joerg 
    493      1.1  joerg 	for (size_t n = 4; n <= 4 * 5555; n += 4)
    494      1.1  joerg 		expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK);
    495      1.1  joerg 
    496      1.1  joerg 	expect(lzma_index_block_count(i) == 5555);
    497      1.1  joerg 
    498      1.1  joerg 	// First Record
    499      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 0));
    500      1.1  joerg 	expect(r.block.total_size == 4 + 8);
    501      1.1  joerg 	expect(r.block.uncompressed_size == 4);
    502      1.1  joerg 	expect(r.block.compressed_file_offset == LZMA_STREAM_HEADER_SIZE);
    503      1.1  joerg 	expect(r.block.uncompressed_file_offset == 0);
    504      1.1  joerg 
    505      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 3));
    506      1.1  joerg 	expect(r.block.total_size == 4 + 8);
    507      1.1  joerg 	expect(r.block.uncompressed_size == 4);
    508      1.1  joerg 	expect(r.block.compressed_file_offset == LZMA_STREAM_HEADER_SIZE);
    509      1.1  joerg 	expect(r.block.uncompressed_file_offset == 0);
    510      1.1  joerg 
    511      1.1  joerg 	// Second Record
    512      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 4));
    513      1.1  joerg 	expect(r.block.total_size == 2 * 4 + 8);
    514      1.1  joerg 	expect(r.block.uncompressed_size == 2 * 4);
    515      1.1  joerg 	expect(r.block.compressed_file_offset
    516      1.1  joerg 			== LZMA_STREAM_HEADER_SIZE + 4 + 8);
    517      1.1  joerg 	expect(r.block.uncompressed_file_offset == 4);
    518      1.1  joerg 
    519      1.1  joerg 	// Last Record
    520      1.1  joerg 	expect(!lzma_index_iter_locate(
    521      1.1  joerg 			&r, lzma_index_uncompressed_size(i) - 1));
    522      1.1  joerg 	expect(r.block.total_size == 4 * 5555 + 8);
    523      1.1  joerg 	expect(r.block.uncompressed_size == 4 * 5555);
    524      1.1  joerg 	expect(r.block.compressed_file_offset == lzma_index_total_size(i)
    525      1.1  joerg 			+ LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
    526      1.1  joerg 	expect(r.block.uncompressed_file_offset
    527      1.1  joerg 			== lzma_index_uncompressed_size(i) - 4 * 5555);
    528      1.1  joerg 
    529      1.1  joerg 	// Allocation chunk boundaries. See INDEX_GROUP_SIZE in
    530      1.1  joerg 	// liblzma/common/index.c.
    531      1.1  joerg 	const size_t group_multiple = 256 * 4;
    532      1.1  joerg 	const size_t radius = 8;
    533      1.1  joerg 	const size_t start = group_multiple - radius;
    534      1.1  joerg 	lzma_vli ubase = 0;
    535      1.1  joerg 	lzma_vli tbase = 0;
    536      1.1  joerg 	size_t n;
    537      1.1  joerg 	for (n = 1; n < start; ++n) {
    538      1.1  joerg 		ubase += n * 4;
    539      1.1  joerg 		tbase += n * 4 + 8;
    540      1.1  joerg 	}
    541      1.1  joerg 
    542      1.1  joerg 	while (n < start + 2 * radius) {
    543      1.1  joerg 		expect(!lzma_index_iter_locate(&r, ubase + n * 4));
    544      1.1  joerg 
    545      1.1  joerg 		expect(r.block.compressed_file_offset == tbase + n * 4 + 8
    546      1.1  joerg 				+ LZMA_STREAM_HEADER_SIZE);
    547      1.1  joerg 		expect(r.block.uncompressed_file_offset == ubase + n * 4);
    548      1.1  joerg 
    549      1.1  joerg 		tbase += n * 4 + 8;
    550      1.1  joerg 		ubase += n * 4;
    551      1.1  joerg 		++n;
    552      1.1  joerg 
    553      1.1  joerg 		expect(r.block.total_size == n * 4 + 8);
    554      1.1  joerg 		expect(r.block.uncompressed_size == n * 4);
    555      1.1  joerg 	}
    556      1.1  joerg 
    557      1.1  joerg 	// Do it also backwards.
    558      1.1  joerg 	while (n > start) {
    559      1.1  joerg 		expect(!lzma_index_iter_locate(&r, ubase + (n - 1) * 4));
    560      1.1  joerg 
    561      1.1  joerg 		expect(r.block.total_size == n * 4 + 8);
    562      1.1  joerg 		expect(r.block.uncompressed_size == n * 4);
    563      1.1  joerg 
    564      1.1  joerg 		--n;
    565      1.1  joerg 		tbase -= n * 4 + 8;
    566      1.1  joerg 		ubase -= n * 4;
    567      1.1  joerg 
    568      1.1  joerg 		expect(r.block.compressed_file_offset == tbase + n * 4 + 8
    569      1.1  joerg 				+ LZMA_STREAM_HEADER_SIZE);
    570      1.1  joerg 		expect(r.block.uncompressed_file_offset == ubase + n * 4);
    571      1.1  joerg 	}
    572      1.1  joerg 
    573      1.1  joerg 	// Test locating in concatenated Index.
    574      1.1  joerg 	lzma_index_end(i, NULL);
    575      1.1  joerg 	i = lzma_index_init(NULL);
    576      1.1  joerg 	expect(i != NULL);
    577      1.1  joerg 	lzma_index_iter_init(&r, i);
    578      1.1  joerg 	for (n = 0; n < group_multiple; ++n)
    579      1.1  joerg 		expect(lzma_index_append(i, NULL, 8, 0) == LZMA_OK);
    580      1.1  joerg 	expect(lzma_index_append(i, NULL, 16, 1) == LZMA_OK);
    581      1.1  joerg 	expect(!lzma_index_iter_locate(&r, 0));
    582      1.1  joerg 	expect(r.block.total_size == 16);
    583      1.1  joerg 	expect(r.block.uncompressed_size == 1);
    584      1.1  joerg 	expect(r.block.compressed_file_offset
    585      1.1  joerg 			== LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
    586      1.1  joerg 	expect(r.block.uncompressed_file_offset == 0);
    587      1.1  joerg 
    588      1.1  joerg 	lzma_index_end(i, NULL);
    589      1.1  joerg }
    590      1.1  joerg 
    591      1.1  joerg 
    592      1.1  joerg static void
    593      1.1  joerg test_corrupt(void)
    594      1.1  joerg {
    595      1.1  joerg 	const size_t alloc_size = 128 * 1024;
    596      1.1  joerg 	uint8_t *buf = malloc(alloc_size);
    597      1.1  joerg 	expect(buf != NULL);
    598      1.1  joerg 	lzma_stream strm = LZMA_STREAM_INIT;
    599      1.1  joerg 
    600      1.1  joerg 	lzma_index *i = create_empty();
    601      1.1  joerg 	expect(lzma_index_append(i, NULL, 0, 1) == LZMA_PROG_ERROR);
    602      1.1  joerg 	lzma_index_end(i, NULL);
    603      1.1  joerg 
    604      1.1  joerg 	// Create a valid Index and corrupt it in different ways.
    605      1.1  joerg 	i = create_small();
    606      1.1  joerg 	expect(lzma_index_encoder(&strm, i) == LZMA_OK);
    607      1.1  joerg 	succeed(coder_loop(&strm, NULL, 0, buf, 20,
    608      1.1  joerg 			LZMA_STREAM_END, LZMA_RUN));
    609      1.1  joerg 	lzma_index_end(i, NULL);
    610      1.1  joerg 
    611      1.1  joerg 	// Wrong Index Indicator
    612      1.1  joerg 	buf[0] ^= 1;
    613      1.1  joerg 	expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
    614      1.1  joerg 	succeed(decoder_loop_ret(&strm, buf, 1, LZMA_DATA_ERROR));
    615      1.1  joerg 	buf[0] ^= 1;
    616      1.1  joerg 
    617      1.1  joerg 	// Wrong Number of Records and thus CRC32 fails.
    618      1.1  joerg 	--buf[1];
    619      1.1  joerg 	expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
    620      1.1  joerg 	succeed(decoder_loop_ret(&strm, buf, 10, LZMA_DATA_ERROR));
    621      1.1  joerg 	++buf[1];
    622      1.1  joerg 
    623      1.1  joerg 	// Padding not NULs
    624      1.1  joerg 	buf[15] ^= 1;
    625      1.1  joerg 	expect(lzma_index_decoder(&strm, &i, MEMLIMIT) == LZMA_OK);
    626      1.1  joerg 	succeed(decoder_loop_ret(&strm, buf, 16, LZMA_DATA_ERROR));
    627      1.1  joerg 
    628      1.1  joerg 	lzma_end(&strm);
    629      1.1  joerg 	free(buf);
    630      1.1  joerg }
    631      1.1  joerg 
    632      1.1  joerg 
    633  1.1.1.2  joerg // Allocator that succeeds for the first two allocation but fails the rest.
    634  1.1.1.2  joerg static void *
    635  1.1.1.2  joerg my_alloc(void *opaque, size_t a, size_t b)
    636  1.1.1.2  joerg {
    637  1.1.1.2  joerg 	(void)opaque;
    638  1.1.1.2  joerg 
    639  1.1.1.2  joerg 	static unsigned count = 0;
    640  1.1.1.2  joerg 	if (++count > 2)
    641  1.1.1.2  joerg 		return NULL;
    642  1.1.1.2  joerg 
    643  1.1.1.2  joerg 	return malloc(a * b);
    644  1.1.1.2  joerg }
    645  1.1.1.2  joerg 
    646  1.1.1.2  joerg static const lzma_allocator my_allocator = { &my_alloc, NULL, NULL };
    647  1.1.1.2  joerg 
    648  1.1.1.2  joerg 
    649      1.1  joerg int
    650      1.1  joerg main(void)
    651      1.1  joerg {
    652      1.1  joerg 	test_equal();
    653      1.1  joerg 
    654      1.1  joerg 	test_overflow();
    655      1.1  joerg 
    656      1.1  joerg 	lzma_index *i = create_empty();
    657      1.1  joerg 	test_many(i);
    658      1.1  joerg 	lzma_index_end(i, NULL);
    659      1.1  joerg 
    660      1.1  joerg 	i = create_small();
    661      1.1  joerg 	test_many(i);
    662      1.1  joerg 	lzma_index_end(i, NULL);
    663      1.1  joerg 
    664      1.1  joerg 	i = create_big();
    665      1.1  joerg 	test_many(i);
    666      1.1  joerg 	lzma_index_end(i, NULL);
    667      1.1  joerg 
    668      1.1  joerg 	test_cat();
    669      1.1  joerg 
    670      1.1  joerg 	test_locate();
    671      1.1  joerg 
    672      1.1  joerg 	test_corrupt();
    673      1.1  joerg 
    674  1.1.1.2  joerg 	// Test for the bug fix 21515d79d778b8730a434f151b07202d52a04611:
    675  1.1.1.2  joerg 	// liblzma: Fix lzma_index_dup() for empty Streams.
    676  1.1.1.2  joerg 	i = create_empty();
    677  1.1.1.2  joerg 	expect(lzma_index_stream_padding(i, 4) == LZMA_OK);
    678  1.1.1.2  joerg 	test_copy(i);
    679  1.1.1.2  joerg 	lzma_index_end(i, NULL);
    680  1.1.1.2  joerg 
    681  1.1.1.2  joerg 	// Test for the bug fix 3bf857edfef51374f6f3fffae3d817f57d3264a0:
    682  1.1.1.2  joerg 	// liblzma: Fix a memory leak in error path of lzma_index_dup().
    683  1.1.1.2  joerg 	// Use Valgrind to see that there are no leaks.
    684  1.1.1.2  joerg 	i = create_small();
    685  1.1.1.2  joerg 	expect(lzma_index_dup(i, &my_allocator) == NULL);
    686  1.1.1.2  joerg 	lzma_index_end(i, NULL);
    687  1.1.1.2  joerg 
    688      1.1  joerg 	return 0;
    689      1.1  joerg }
    690