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