]> icculus.org git repositories - icculus/xz.git/blob - tests/test_block_header.c
Fixed the test that should have been fixed as part
[icculus/xz.git] / tests / test_block_header.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       test_block_header.c
4 /// \brief      Tests Block Header coders
5 //
6 //  Copyright (C) 2007 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "tests.h"
21
22
23 static uint8_t buf[LZMA_BLOCK_HEADER_SIZE_MAX];
24 static lzma_block known_options;
25 static lzma_block decoded_options;
26
27 static lzma_options_lzma opt_lzma;
28
29 static lzma_filter filters_none[1] = {
30         {
31                 .id = LZMA_VLI_UNKNOWN,
32         },
33 };
34
35
36 static lzma_filter filters_one[2] = {
37         {
38                 .id = LZMA_FILTER_LZMA2,
39                 .options = &opt_lzma,
40         }, {
41                 .id = LZMA_VLI_UNKNOWN,
42         }
43 };
44
45
46 static lzma_filter filters_four[5] = {
47         {
48                 .id = LZMA_FILTER_X86,
49                 .options = NULL,
50         }, {
51                 .id = LZMA_FILTER_X86,
52                 .options = NULL,
53         }, {
54                 .id = LZMA_FILTER_X86,
55                 .options = NULL,
56         }, {
57                 .id = LZMA_FILTER_LZMA2,
58                 .options = &opt_lzma,
59         }, {
60                 .id = LZMA_VLI_UNKNOWN,
61         }
62 };
63
64
65 static lzma_filter filters_five[6] = {
66         {
67                 .id = LZMA_FILTER_X86,
68                 .options = NULL,
69         }, {
70                 .id = LZMA_FILTER_X86,
71                 .options = NULL,
72         }, {
73                 .id = LZMA_FILTER_X86,
74                 .options = NULL,
75         }, {
76                 .id = LZMA_FILTER_X86,
77                 .options = NULL,
78         }, {
79                 .id = LZMA_FILTER_LZMA2,
80                 .options = &opt_lzma,
81         }, {
82                 .id = LZMA_VLI_UNKNOWN,
83         }
84 };
85
86
87 static void
88 code(void)
89 {
90         expect(lzma_block_header_encode(&known_options, buf) == LZMA_OK);
91
92         lzma_filter filters[LZMA_BLOCK_FILTERS_MAX + 1];
93         memcrap(filters, sizeof(filters));
94         memcrap(&decoded_options, sizeof(decoded_options));
95
96         decoded_options.header_size = known_options.header_size;
97         decoded_options.check = known_options.check;
98         decoded_options.filters = filters;
99         expect(lzma_block_header_decode(&decoded_options, NULL, buf)
100                         == LZMA_OK);
101
102         expect(known_options.compressed_size
103                         == decoded_options.compressed_size);
104         expect(known_options.uncompressed_size
105                         == decoded_options.uncompressed_size);
106
107         for (size_t i = 0; known_options.filters[i].id
108                         != LZMA_VLI_UNKNOWN; ++i)
109                 expect(known_options.filters[i].id == filters[i].id);
110
111         for (size_t i = 0; i < LZMA_BLOCK_FILTERS_MAX; ++i)
112                 free(decoded_options.filters[i].options);
113 }
114
115
116 static void
117 test1(void)
118 {
119         known_options = (lzma_block){
120                 .check = LZMA_CHECK_NONE,
121                 .compressed_size = LZMA_VLI_UNKNOWN,
122                 .uncompressed_size = LZMA_VLI_UNKNOWN,
123                 .filters = NULL,
124         };
125
126         expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
127
128         known_options.filters = filters_none;
129         expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
130
131         known_options.filters = filters_five;
132         expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
133
134         known_options.filters = filters_one;
135         expect(lzma_block_header_size(&known_options) == LZMA_OK);
136
137         known_options.check = 999; // Some invalid value, which gets ignored.
138         expect(lzma_block_header_size(&known_options) == LZMA_OK);
139
140         known_options.compressed_size = 5; // Not a multiple of four.
141         expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
142
143         known_options.compressed_size = 0; // Cannot be zero.
144         expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
145
146         known_options.compressed_size = LZMA_VLI_UNKNOWN;
147         known_options.uncompressed_size = 0;
148         expect(lzma_block_header_size(&known_options) == LZMA_OK);
149
150         known_options.uncompressed_size = LZMA_VLI_MAX + 1;
151         expect(lzma_block_header_size(&known_options) == LZMA_PROG_ERROR);
152 }
153
154
155 static void
156 test2(void)
157 {
158         known_options = (lzma_block){
159                 .check = LZMA_CHECK_CRC32,
160                 .compressed_size = LZMA_VLI_UNKNOWN,
161                 .uncompressed_size = LZMA_VLI_UNKNOWN,
162                 .filters = filters_four,
163         };
164
165         expect(lzma_block_header_size(&known_options) == LZMA_OK);
166         code();
167
168         known_options.compressed_size = 123456;
169         known_options.uncompressed_size = 234567;
170         expect(lzma_block_header_size(&known_options) == LZMA_OK);
171         code();
172
173         // We can make the sizes smaller while keeping the header size
174         // the same.
175         known_options.compressed_size = 12;
176         known_options.uncompressed_size = 23;
177         code();
178 }
179
180
181 static void
182 test3(void)
183 {
184         known_options = (lzma_block){
185                 .check = LZMA_CHECK_CRC32,
186                 .compressed_size = LZMA_VLI_UNKNOWN,
187                 .uncompressed_size = LZMA_VLI_UNKNOWN,
188                 .filters = filters_one,
189         };
190
191         expect(lzma_block_header_size(&known_options) == LZMA_OK);
192         known_options.header_size += 4;
193         expect(lzma_block_header_encode(&known_options, buf) == LZMA_OK);
194
195         lzma_filter filters[LZMA_BLOCK_FILTERS_MAX + 1];
196         decoded_options.header_size = known_options.header_size;
197         decoded_options.check = known_options.check;
198         decoded_options.filters = filters;
199
200         // Wrong size
201         ++buf[0];
202         expect(lzma_block_header_decode(&decoded_options, NULL, buf)
203                         == LZMA_PROG_ERROR);
204         --buf[0];
205
206         // Wrong CRC32
207         buf[known_options.header_size - 1] ^= 1;
208         expect(lzma_block_header_decode(&decoded_options, NULL, buf)
209                         == LZMA_DATA_ERROR);
210         buf[known_options.header_size - 1] ^= 1;
211
212         // Unsupported filter
213         // NOTE: This may need updating when new IDs become supported.
214         buf[2] ^= 0x1F;
215         integer_write_32(buf + known_options.header_size - 4,
216                         lzma_crc32(buf, known_options.header_size - 4, 0));
217         expect(lzma_block_header_decode(&decoded_options, NULL, buf)
218                         == LZMA_OPTIONS_ERROR);
219         buf[2] ^= 0x1F;
220
221         // Non-nul Padding
222         buf[known_options.header_size - 4 - 1] ^= 1;
223         integer_write_32(buf + known_options.header_size - 4,
224                         lzma_crc32(buf, known_options.header_size - 4, 0));
225         expect(lzma_block_header_decode(&decoded_options, NULL, buf)
226                         == LZMA_OPTIONS_ERROR);
227         buf[known_options.header_size - 4 - 1] ^= 1;
228 }
229
230
231 int
232 main(void)
233 {
234         lzma_init();
235         succeed(lzma_lzma_preset(&opt_lzma, 1));
236
237         test1();
238         test2();
239         test3();
240
241         return 0;
242 }