]> icculus.org git repositories - icculus/xz.git/blob - tests/test_block_header.c
Put the interesting parts of XZ Utils into the public domain.
[icculus/xz.git] / tests / test_block_header.c
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
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
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
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
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         integer_write_32(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         integer_write_32(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
231 main(void)
232 {
233         succeed(lzma_lzma_preset(&opt_lzma, 1));
234
235         test1();
236         test2();
237         test3();
238
239         return 0;
240 }