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