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