xref: /minix3/external/public-domain/xz/dist/tests/test_block_header.c (revision 5a645f22a86f086849945a5dd6acbf59f38c913a)
1*5a645f22SBen Gras ///////////////////////////////////////////////////////////////////////////////
2*5a645f22SBen Gras //
3*5a645f22SBen Gras /// \file       test_block_header.c
4*5a645f22SBen Gras /// \brief      Tests Block Header coders
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 
16*5a645f22SBen Gras static uint8_t buf[LZMA_BLOCK_HEADER_SIZE_MAX];
17*5a645f22SBen Gras static lzma_block known_options;
18*5a645f22SBen Gras static lzma_block decoded_options;
19*5a645f22SBen Gras 
20*5a645f22SBen Gras static lzma_options_lzma opt_lzma;
21*5a645f22SBen Gras 
22*5a645f22SBen Gras static lzma_filter filters_none[1] = {
23*5a645f22SBen Gras 	{
24*5a645f22SBen Gras 		.id = LZMA_VLI_UNKNOWN,
25*5a645f22SBen Gras 	},
26*5a645f22SBen Gras };
27*5a645f22SBen Gras 
28*5a645f22SBen Gras 
29*5a645f22SBen Gras static lzma_filter filters_one[2] = {
30*5a645f22SBen Gras 	{
31*5a645f22SBen Gras 		.id = LZMA_FILTER_LZMA2,
32*5a645f22SBen Gras 		.options = &opt_lzma,
33*5a645f22SBen Gras 	}, {
34*5a645f22SBen Gras 		.id = LZMA_VLI_UNKNOWN,
35*5a645f22SBen Gras 	}
36*5a645f22SBen Gras };
37*5a645f22SBen Gras 
38*5a645f22SBen Gras 
39*5a645f22SBen Gras static lzma_filter filters_four[5] = {
40*5a645f22SBen Gras 	{
41*5a645f22SBen Gras 		.id = LZMA_FILTER_X86,
42*5a645f22SBen Gras 		.options = NULL,
43*5a645f22SBen Gras 	}, {
44*5a645f22SBen Gras 		.id = LZMA_FILTER_X86,
45*5a645f22SBen Gras 		.options = NULL,
46*5a645f22SBen Gras 	}, {
47*5a645f22SBen Gras 		.id = LZMA_FILTER_X86,
48*5a645f22SBen Gras 		.options = NULL,
49*5a645f22SBen Gras 	}, {
50*5a645f22SBen Gras 		.id = LZMA_FILTER_LZMA2,
51*5a645f22SBen Gras 		.options = &opt_lzma,
52*5a645f22SBen Gras 	}, {
53*5a645f22SBen Gras 		.id = LZMA_VLI_UNKNOWN,
54*5a645f22SBen Gras 	}
55*5a645f22SBen Gras };
56*5a645f22SBen Gras 
57*5a645f22SBen Gras 
58*5a645f22SBen Gras static lzma_filter filters_five[6] = {
59*5a645f22SBen Gras 	{
60*5a645f22SBen Gras 		.id = LZMA_FILTER_X86,
61*5a645f22SBen Gras 		.options = NULL,
62*5a645f22SBen Gras 	}, {
63*5a645f22SBen Gras 		.id = LZMA_FILTER_X86,
64*5a645f22SBen Gras 		.options = NULL,
65*5a645f22SBen Gras 	}, {
66*5a645f22SBen Gras 		.id = LZMA_FILTER_X86,
67*5a645f22SBen Gras 		.options = NULL,
68*5a645f22SBen Gras 	}, {
69*5a645f22SBen Gras 		.id = LZMA_FILTER_X86,
70*5a645f22SBen Gras 		.options = NULL,
71*5a645f22SBen Gras 	}, {
72*5a645f22SBen Gras 		.id = LZMA_FILTER_LZMA2,
73*5a645f22SBen Gras 		.options = &opt_lzma,
74*5a645f22SBen Gras 	}, {
75*5a645f22SBen Gras 		.id = LZMA_VLI_UNKNOWN,
76*5a645f22SBen Gras 	}
77*5a645f22SBen Gras };
78*5a645f22SBen Gras 
79*5a645f22SBen Gras 
80*5a645f22SBen Gras static void
code(void)81*5a645f22SBen Gras code(void)
82*5a645f22SBen Gras {
83*5a645f22SBen Gras 	expect(lzma_block_header_encode(&known_options, buf) == LZMA_OK);
84*5a645f22SBen Gras 
85*5a645f22SBen Gras 	lzma_filter filters[LZMA_FILTERS_MAX + 1];
86*5a645f22SBen Gras 	memcrap(filters, sizeof(filters));
87*5a645f22SBen Gras 	memcrap(&decoded_options, sizeof(decoded_options));
88*5a645f22SBen Gras 
89*5a645f22SBen Gras 	decoded_options.header_size = known_options.header_size;
90*5a645f22SBen Gras 	decoded_options.check = known_options.check;
91*5a645f22SBen Gras 	decoded_options.filters = filters;
92*5a645f22SBen Gras 	expect(lzma_block_header_decode(&decoded_options, NULL, buf)
93*5a645f22SBen Gras 			== LZMA_OK);
94*5a645f22SBen Gras 
95*5a645f22SBen Gras 	expect(known_options.compressed_size
96*5a645f22SBen Gras 			== decoded_options.compressed_size);
97*5a645f22SBen Gras 	expect(known_options.uncompressed_size
98*5a645f22SBen Gras 			== decoded_options.uncompressed_size);
99*5a645f22SBen Gras 
100*5a645f22SBen Gras 	for (size_t i = 0; known_options.filters[i].id
101*5a645f22SBen Gras 			!= LZMA_VLI_UNKNOWN; ++i)
102*5a645f22SBen Gras 		expect(known_options.filters[i].id == filters[i].id);
103*5a645f22SBen Gras 
104*5a645f22SBen Gras 	for (size_t i = 0; i < LZMA_FILTERS_MAX; ++i)
105*5a645f22SBen Gras 		free(decoded_options.filters[i].options);
106*5a645f22SBen Gras }
107*5a645f22SBen Gras 
108*5a645f22SBen Gras 
109*5a645f22SBen Gras static void
test1(void)110*5a645f22SBen Gras test1(void)
111*5a645f22SBen Gras {
112*5a645f22SBen Gras 	known_options = (lzma_block){
113*5a645f22SBen Gras 		.check = LZMA_CHECK_NONE,
114*5a645f22SBen Gras 		.compressed_size = LZMA_VLI_UNKNOWN,
115*5a645f22SBen Gras 		.uncompressed_size = LZMA_VLI_UNKNOWN,
116*5a645f22SBen Gras 		.filters = NULL,
117*5a645f22SBen Gras 	};
118*5a645f22SBen Gras 
119*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
120*5a645f22SBen Gras 
121*5a645f22SBen Gras 	known_options.filters = filters_none;
122*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
123*5a645f22SBen Gras 
124*5a645f22SBen Gras 	known_options.filters = filters_five;
125*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
126*5a645f22SBen Gras 
127*5a645f22SBen Gras 	known_options.filters = filters_one;
128*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_OK);
129*5a645f22SBen Gras 
130*5a645f22SBen Gras 	known_options.check = 999; // Some invalid value, which gets ignored.
131*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_OK);
132*5a645f22SBen Gras 
133*5a645f22SBen Gras 	known_options.compressed_size = 5;
134*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_OK);
135*5a645f22SBen Gras 
136*5a645f22SBen Gras 	known_options.compressed_size = 0; // Cannot be zero.
137*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
138*5a645f22SBen Gras 
139*5a645f22SBen Gras 	// LZMA_VLI_MAX is too big to keep the total size of the Block
140*5a645f22SBen Gras 	// a valid VLI, but lzma_block_header_size() is not meant
141*5a645f22SBen Gras 	// to validate it. (lzma_block_header_encode() must validate it.)
142*5a645f22SBen Gras 	known_options.compressed_size = LZMA_VLI_MAX;
143*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_OK);
144*5a645f22SBen Gras 
145*5a645f22SBen Gras 	known_options.compressed_size = LZMA_VLI_UNKNOWN;
146*5a645f22SBen Gras 	known_options.uncompressed_size = 0;
147*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_OK);
148*5a645f22SBen Gras 
149*5a645f22SBen Gras 	known_options.uncompressed_size = LZMA_VLI_MAX + 1;
150*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
151*5a645f22SBen Gras }
152*5a645f22SBen Gras 
153*5a645f22SBen Gras 
154*5a645f22SBen Gras static void
test2(void)155*5a645f22SBen Gras test2(void)
156*5a645f22SBen Gras {
157*5a645f22SBen Gras 	known_options = (lzma_block){
158*5a645f22SBen Gras 		.check = LZMA_CHECK_CRC32,
159*5a645f22SBen Gras 		.compressed_size = LZMA_VLI_UNKNOWN,
160*5a645f22SBen Gras 		.uncompressed_size = LZMA_VLI_UNKNOWN,
161*5a645f22SBen Gras 		.filters = filters_four,
162*5a645f22SBen Gras 	};
163*5a645f22SBen Gras 
164*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_OK);
165*5a645f22SBen Gras 	code();
166*5a645f22SBen Gras 
167*5a645f22SBen Gras 	known_options.compressed_size = 123456;
168*5a645f22SBen Gras 	known_options.uncompressed_size = 234567;
169*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_OK);
170*5a645f22SBen Gras 	code();
171*5a645f22SBen Gras 
172*5a645f22SBen Gras 	// We can make the sizes smaller while keeping the header size
173*5a645f22SBen Gras 	// the same.
174*5a645f22SBen Gras 	known_options.compressed_size = 12;
175*5a645f22SBen Gras 	known_options.uncompressed_size = 23;
176*5a645f22SBen Gras 	code();
177*5a645f22SBen Gras }
178*5a645f22SBen Gras 
179*5a645f22SBen Gras 
180*5a645f22SBen Gras static void
test3(void)181*5a645f22SBen Gras test3(void)
182*5a645f22SBen Gras {
183*5a645f22SBen Gras 	known_options = (lzma_block){
184*5a645f22SBen Gras 		.check = LZMA_CHECK_CRC32,
185*5a645f22SBen Gras 		.compressed_size = LZMA_VLI_UNKNOWN,
186*5a645f22SBen Gras 		.uncompressed_size = LZMA_VLI_UNKNOWN,
187*5a645f22SBen Gras 		.filters = filters_one,
188*5a645f22SBen Gras 	};
189*5a645f22SBen Gras 
190*5a645f22SBen Gras 	expect(lzma_block_header_size(&known_options) == LZMA_OK);
191*5a645f22SBen Gras 	known_options.header_size += 4;
192*5a645f22SBen Gras 	expect(lzma_block_header_encode(&known_options, buf) == LZMA_OK);
193*5a645f22SBen Gras 
194*5a645f22SBen Gras 	lzma_filter filters[LZMA_FILTERS_MAX + 1];
195*5a645f22SBen Gras 	decoded_options.header_size = known_options.header_size;
196*5a645f22SBen Gras 	decoded_options.check = known_options.check;
197*5a645f22SBen Gras 	decoded_options.filters = filters;
198*5a645f22SBen Gras 
199*5a645f22SBen Gras 	// Wrong size
200*5a645f22SBen Gras 	++buf[0];
201*5a645f22SBen Gras 	expect(lzma_block_header_decode(&decoded_options, NULL, buf)
202*5a645f22SBen Gras 			== LZMA_PROG_ERROR);
203*5a645f22SBen Gras 	--buf[0];
204*5a645f22SBen Gras 
205*5a645f22SBen Gras 	// Wrong CRC32
206*5a645f22SBen Gras 	buf[known_options.header_size - 1] ^= 1;
207*5a645f22SBen Gras 	expect(lzma_block_header_decode(&decoded_options, NULL, buf)
208*5a645f22SBen Gras 			== LZMA_DATA_ERROR);
209*5a645f22SBen Gras 	buf[known_options.header_size - 1] ^= 1;
210*5a645f22SBen Gras 
211*5a645f22SBen Gras 	// Unsupported filter
212*5a645f22SBen Gras 	// NOTE: This may need updating when new IDs become supported.
213*5a645f22SBen Gras 	buf[2] ^= 0x1F;
214*5a645f22SBen Gras 	unaligned_write32le(buf + known_options.header_size - 4,
215*5a645f22SBen Gras 			lzma_crc32(buf, known_options.header_size - 4, 0));
216*5a645f22SBen Gras 	expect(lzma_block_header_decode(&decoded_options, NULL, buf)
217*5a645f22SBen Gras 			== LZMA_OPTIONS_ERROR);
218*5a645f22SBen Gras 	buf[2] ^= 0x1F;
219*5a645f22SBen Gras 
220*5a645f22SBen Gras 	// Non-nul Padding
221*5a645f22SBen Gras 	buf[known_options.header_size - 4 - 1] ^= 1;
222*5a645f22SBen Gras 	unaligned_write32le(buf + known_options.header_size - 4,
223*5a645f22SBen Gras 			lzma_crc32(buf, known_options.header_size - 4, 0));
224*5a645f22SBen Gras 	expect(lzma_block_header_decode(&decoded_options, NULL, buf)
225*5a645f22SBen Gras 			== LZMA_OPTIONS_ERROR);
226*5a645f22SBen Gras 	buf[known_options.header_size - 4 - 1] ^= 1;
227*5a645f22SBen Gras }
228*5a645f22SBen Gras 
229*5a645f22SBen Gras 
230*5a645f22SBen Gras int
main(void)231*5a645f22SBen Gras main(void)
232*5a645f22SBen Gras {
233*5a645f22SBen Gras 	succeed(lzma_lzma_preset(&opt_lzma, 1));
234*5a645f22SBen Gras 
235*5a645f22SBen Gras 	test1();
236*5a645f22SBen Gras 	test2();
237*5a645f22SBen Gras 	test3();
238*5a645f22SBen Gras 
239*5a645f22SBen Gras 	return 0;
240*5a645f22SBen Gras }
241