source: mainline/boot/generic/src/inflate.c@ 39916d6

Last change on this file since 39916d6 was 39916d6, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

License information for some third party code

  • Property mode set to 100644
File size: 15.1 KB
RevLine 
[4872160]1/*
[39916d6]2 * SPDX-FileCopyrightText: 2002-2010 Mark Adler
[d7f7a4a]3 * SPDX-FileCopyrightText: 2010 Martin Decky
4 *
[39916d6]5 * SPDX-License-Identifier: BSD-3-Clause AND LicenseRef-InflateLicense
[4872160]6 */
7
8/** @file
9 * @brief Implementation of inflate decompression
10 *
11 * A simple inflate implementation (decompression of `deflate' stream as
12 * described by RFC 1951) based on puff.c by Mark Adler. It is not optimized
13 * for speed but for readability as it is used as part of the bootloader and
14 * any miss-optimization might be hard to debug.
15 *
16 * All dynamically allocated memory memory is taken from the stack. The
17 * stack usage should be typically bounded by 2 KB.
18 */
19
[d735e2e]20#include <stdbool.h>
[de1712e]21#include <stddef.h>
[10d65d70]22#include <stdint.h>
[4872160]23#include <errno.h>
24#include <memstr.h>
25#include <inflate.h>
26
27/** Maximum bits in the Huffman code */
28#define MAX_HUFFMAN_BIT 15
29
30/** Number of length codes */
31#define MAX_LEN 29
32/** Number of distance codes */
33#define MAX_DIST 30
34/** Number of order codes */
35#define MAX_ORDER 19
36/** Number of literal/length codes */
37#define MAX_LITLEN 286
38/** Number of fixed literal/length codes */
39#define MAX_FIXED_LITLEN 288
40
41/** Number of all codes */
42#define MAX_CODE (MAX_LITLEN + MAX_DIST)
43
44/** Check for input buffer overrun condition */
45#define CHECK_OVERRUN(state) \
46 do { \
47 if ((state).overrun) \
48 return ELIMIT; \
49 } while (false)
50
51/** Inflate algorithm state
52 *
53 */
54typedef struct {
55 uint8_t *dest; /**< Output buffer */
56 size_t destlen; /**< Output buffer size */
57 size_t destcnt; /**< Position in the output buffer */
[a35b458]58
[63a045c]59 const uint8_t *src; /**< Input buffer */
[4872160]60 size_t srclen; /**< Input buffer size */
61 size_t srccnt; /**< Position in the input buffer */
[a35b458]62
[4872160]63 uint16_t bitbuf; /**< Bit buffer */
64 size_t bitlen; /**< Number of bits in the bit buffer */
[a35b458]65
[4872160]66 bool overrun; /**< Overrun condition */
67} inflate_state_t;
68
69/** Huffman code description
70 *
71 */
72typedef struct {
73 uint16_t *count; /**< Array of symbol counts */
74 uint16_t *symbol; /**< Array of symbols */
75} huffman_t;
76
77/** Length codes
78 *
79 */
80static const uint16_t lens[MAX_LEN] = {
81 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
82 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
83};
84
85/** Extended length codes
86 *
87 */
88static const uint16_t lens_ext[MAX_LEN] = {
89 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
90 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
91};
92
93/** Distance codes
94 *
95 */
96static const uint16_t dists[MAX_DIST] = {
97 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
98 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
99 8193, 12289, 16385, 24577
100};
101
102/** Extended distance codes
103 *
104 */
105static const uint16_t dists_ext[MAX_DIST] = {
106 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
107 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
108 12, 12, 13, 13
109};
110
111/** Order codes
112 *
113 */
114static const short order[MAX_ORDER] = {
115 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
116};
117
118/** Static length symbol counts
119 *
120 */
121static uint16_t len_count[MAX_HUFFMAN_BIT + 1] = {
122 0, 0, 0, 0, 0, 0, 0, 24, 152, 112, 0, 0, 0, 0, 0, 0
123};
124
125/** Static length symbols
126 *
127 */
128static uint16_t len_symbol[MAX_FIXED_LITLEN] = {
129 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
130 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, 1, 2,
131 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
132 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
133 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
134 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
135 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
136 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
137 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
138 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
139 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
140 140, 141, 142, 143, 280, 281, 282, 283, 284, 285, 286, 287, 144,
141 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
142 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
143 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
144 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
145 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
146 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
147 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235,
148 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248,
149 249, 250, 251, 252, 253, 254, 255
150};
151
152/** Static distance symbol counts
153 *
154 */
155static uint16_t dist_count[MAX_HUFFMAN_BIT + 1] = {
156 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
157};
158
159/** Static distance symbols
160 *
161 */
162static uint16_t dist_symbol[MAX_DIST] = {
163 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
164 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
165};
166
167/** Huffman code for lengths
168 *
169 */
170static huffman_t len_code = {
171 .count = len_count,
172 .symbol = len_symbol
173};
174
175/** Huffman code for distances
176 *
177 */
178static huffman_t dist_code = {
179 .count = dist_count,
180 .symbol = dist_symbol
181};
182
183/** Get bits from the bit buffer
184 *
185 * @param state Inflate state.
186 * @param cnt Number of bits to return (at most 16).
187 *
188 * @return Returned bits.
189 *
190 */
191static inline uint16_t get_bits(inflate_state_t *state, size_t cnt)
192{
193 /* Bit accumulator for at least 20 bits */
194 uint32_t val = state->bitbuf;
[a35b458]195
[4872160]196 while (state->bitlen < cnt) {
197 if (state->srccnt == state->srclen) {
198 state->overrun = true;
199 return 0;
200 }
[a35b458]201
[4872160]202 /* Load 8 more bits */
203 val |= ((uint32_t) state->src[state->srccnt]) << state->bitlen;
204 state->srccnt++;
205 state->bitlen += 8;
206 }
[a35b458]207
[4872160]208 /* Update bits in the buffer */
209 state->bitbuf = (uint16_t) (val >> cnt);
210 state->bitlen -= cnt;
[a35b458]211
[4872160]212 return ((uint16_t) (val & ((1 << cnt) - 1)));
213}
214
215/** Decode `stored' block
216 *
217 * @param state Inflate state.
218 *
219 * @return EOK on success.
220 * @return ELIMIT on input buffer overrun.
221 * @return ENOMEM on output buffer overrun.
222 * @return EINVAL on invalid data.
223 *
224 */
225static int inflate_stored(inflate_state_t *state)
226{
227 /* Discard bits in the bit buffer */
228 state->bitbuf = 0;
229 state->bitlen = 0;
[a35b458]230
[4872160]231 if (state->srccnt + 4 > state->srclen)
232 return ELIMIT;
[a35b458]233
[4872160]234 uint16_t len =
235 state->src[state->srccnt] | (state->src[state->srccnt + 1] << 8);
236 uint16_t len_compl =
237 state->src[state->srccnt + 2] | (state->src[state->srccnt + 3] << 8);
[a35b458]238
[4872160]239 /* Check block length and its complement */
240 if (((int16_t) len) != ~((int16_t) len_compl))
241 return EINVAL;
[a35b458]242
[4872160]243 state->srccnt += 4;
[a35b458]244
[4872160]245 /* Check input buffer size */
246 if (state->srccnt + len > state->srclen)
247 return ELIMIT;
[a35b458]248
[4872160]249 /* Check output buffer size */
250 if (state->destcnt + len > state->destlen)
251 return ENOMEM;
[a35b458]252
[4872160]253 /* Copy data */
254 memcpy(state->dest + state->destcnt, state->src + state->srccnt, len);
255 state->srccnt += len;
256 state->destcnt += len;
[a35b458]257
[4872160]258 return EOK;
259}
260
261/** Decode a symbol using the Huffman code
262 *
263 * @param state Inflate state.
264 * @param huffman Huffman code.
265 * @param symbol Decoded symbol.
266 *
267 * @param EOK on success.
268 * @param EINVAL on invalid Huffman code.
269 *
270 */
271static int huffman_decode(inflate_state_t *state, huffman_t *huffman,
272 uint16_t *symbol)
273{
[63a045c]274 /* Decode bits */
[904b1bc]275 uint16_t code = 0;
276
277 /* First code of the given length */
278 size_t first = 0;
279
280 /*
281 * Index of the first code of the given length
282 * in the symbol table
283 */
284 size_t index = 0;
[a35b458]285
[63a045c]286 /* Current number of bits in the code */
287 size_t len;
288
[4872160]289 for (len = 1; len <= MAX_HUFFMAN_BIT; len++) {
290 /* Get next bit */
291 code |= get_bits(state, 1);
292 CHECK_OVERRUN(*state);
[a35b458]293
[4872160]294 uint16_t count = huffman->count[len];
295 if (code < first + count) {
296 /* Return decoded symbol */
297 *symbol = huffman->symbol[index + code - first];
298 return EOK;
299 }
[a35b458]300
[4872160]301 /* Update for next length */
302 index += count;
303 first += count;
304 first <<= 1;
305 code <<= 1;
306 }
[a35b458]307
[4872160]308 return EINVAL;
309}
310
311/** Construct Huffman tables from canonical Huffman code
312 *
313 * @param huffman Constructed Huffman tables.
314 * @param length Lengths of the canonical Huffman code.
315 * @param n Number of lengths.
316 *
317 * @return 0 if the Huffman code set is complete.
318 * @return Negative value for an over-subscribed code set.
319 * @return Positive value for an incomplete code set.
320 *
321 */
322static int16_t huffman_construct(huffman_t *huffman, uint16_t *length, size_t n)
323{
324 /* Count number of codes for each length */
325 size_t len;
326 for (len = 0; len <= MAX_HUFFMAN_BIT; len++)
327 huffman->count[len] = 0;
[a35b458]328
[4872160]329 /* We assume that the lengths are within bounds */
330 size_t symbol;
331 for (symbol = 0; symbol < n; symbol++)
332 huffman->count[length[symbol]]++;
[a35b458]333
[4872160]334 if (huffman->count[0] == n) {
335 /* The code is complete, but decoding will fail */
336 return 0;
337 }
[a35b458]338
[4872160]339 /* Check for an over-subscribed or incomplete set of lengths */
340 int16_t left = 1;
341 for (len = 1; len <= MAX_HUFFMAN_BIT; len++) {
342 left <<= 1;
343 left -= huffman->count[len];
344 if (left < 0) {
345 /* Over-subscribed */
346 return left;
347 }
348 }
[a35b458]349
[4872160]350 /* Generate offsets into symbol table */
351 uint16_t offs[MAX_HUFFMAN_BIT + 1];
[a35b458]352
[4872160]353 offs[1] = 0;
354 for (len = 1; len < MAX_HUFFMAN_BIT; len++)
355 offs[len + 1] = offs[len] + huffman->count[len];
[a35b458]356
[4872160]357 for (symbol = 0; symbol < n; symbol++) {
358 if (length[symbol] != 0) {
359 huffman->symbol[offs[length[symbol]]] = symbol;
360 offs[length[symbol]]++;
361 }
362 }
[a35b458]363
[4872160]364 return left;
365}
366
367/** Decode literal/length and distance codes
368 *
369 * Decode until end-of-block code.
370 *
371 * @param state Inflate state.
372 * @param len_code Huffman code for literal/length.
373 * @param dist_code Huffman code for distance.
374 *
375 * @return EOK on success.
376 * @return ENOENT on distance too large.
377 * @return EINVAL on invalid Huffman code.
378 * @return ELIMIT on input buffer overrun.
379 * @return ENOMEM on output buffer overrun.
380 *
381 */
[3bacee1]382static int inflate_codes(inflate_state_t *state, huffman_t *len_code,
383 huffman_t *dist_code)
[4872160]384{
385 uint16_t symbol;
[a35b458]386
[4872160]387 do {
388 int err = huffman_decode(state, len_code, &symbol);
389 if (err != EOK) {
390 /* Error decoding */
391 return err;
392 }
[a35b458]393
[4872160]394 if (symbol < 256) {
395 /* Write out literal */
396 if (state->destcnt == state->destlen)
397 return ENOMEM;
[a35b458]398
[4872160]399 state->dest[state->destcnt] = (uint8_t) symbol;
400 state->destcnt++;
401 } else if (symbol > 256) {
402 /* Compute length */
403 symbol -= 257;
404 if (symbol >= 29)
405 return EINVAL;
[a35b458]406
[4872160]407 size_t len = lens[symbol] + get_bits(state, lens_ext[symbol]);
408 CHECK_OVERRUN(*state);
[a35b458]409
[4872160]410 /* Get distance */
411 err = huffman_decode(state, dist_code, &symbol);
412 if (err != EOK)
413 return err;
[a35b458]414
[4872160]415 size_t dist = dists[symbol] + get_bits(state, dists_ext[symbol]);
416 if (dist > state->destcnt)
417 return ENOENT;
[a35b458]418
[4872160]419 if (state->destcnt + len > state->destlen)
420 return ENOMEM;
[a35b458]421
[4872160]422 while (len > 0) {
423 /* Copy len bytes from distance bytes back */
[3bacee1]424 state->dest[state->destcnt] =
425 state->dest[state->destcnt - dist];
[4872160]426 state->destcnt++;
427 len--;
428 }
429 }
430 } while (symbol != 256);
[a35b458]431
[4872160]432 return EOK;
433}
434
435/** Decode `fixed codes' block
436 *
437 * @param state Inflate state.
438 * @param len_code Huffman code for literal/length.
439 * @param dist_code Huffman code for distance.
440 *
441 * @return EOK on success.
442 * @return ENOENT on distance too large.
443 * @return EINVAL on invalid Huffman code.
444 * @return ELIMIT on input buffer overrun.
445 * @return ENOMEM on output buffer overrun.
446 *
447 */
448static int inflate_fixed(inflate_state_t *state, huffman_t *len_code,
449 huffman_t *dist_code)
450{
451 return inflate_codes(state, len_code, dist_code);
452}
453
454/** Decode `dynamic codes' block
455 *
456 * @param state Inflate state.
457 *
458 * @return EOK on success.
459 * @return ENOENT on distance too large.
460 * @return EINVAL on invalid Huffman code.
461 * @return ELIMIT on input buffer overrun.
462 * @return ENOMEM on output buffer overrun.
463 *
464 */
465static int inflate_dynamic(inflate_state_t *state)
466{
467 uint16_t length[MAX_CODE];
468 uint16_t dyn_len_count[MAX_HUFFMAN_BIT + 1];
469 uint16_t dyn_len_symbol[MAX_LITLEN];
470 uint16_t dyn_dist_count[MAX_HUFFMAN_BIT + 1];
471 uint16_t dyn_dist_symbol[MAX_DIST];
472 huffman_t dyn_len_code;
473 huffman_t dyn_dist_code;
[a35b458]474
[4872160]475 dyn_len_code.count = dyn_len_count;
476 dyn_len_code.symbol = dyn_len_symbol;
[a35b458]477
[4872160]478 dyn_dist_code.count = dyn_dist_count;
479 dyn_dist_code.symbol = dyn_dist_symbol;
[a35b458]480
[4872160]481 /* Get number of bits in each table */
482 uint16_t nlen = get_bits(state, 5) + 257;
483 CHECK_OVERRUN(*state);
[a35b458]484
[4872160]485 uint16_t ndist = get_bits(state, 5) + 1;
486 CHECK_OVERRUN(*state);
[a35b458]487
[4872160]488 uint16_t ncode = get_bits(state, 4) + 4;
489 CHECK_OVERRUN(*state);
[a35b458]490
[3bacee1]491 if ((nlen > MAX_LITLEN) || (ndist > MAX_DIST) ||
492 (ncode > MAX_ORDER))
[4872160]493 return EINVAL;
[a35b458]494
[4872160]495 /* Read code length code lengths */
496 uint16_t index;
497 for (index = 0; index < ncode; index++) {
498 length[order[index]] = get_bits(state, 3);
499 CHECK_OVERRUN(*state);
500 }
[a35b458]501
[4872160]502 /* Set missing lengths to zero */
503 for (index = ncode; index < MAX_ORDER; index++)
504 length[order[index]] = 0;
[a35b458]505
[4872160]506 /* Build Huffman code */
507 int16_t rc = huffman_construct(&dyn_len_code, length, MAX_ORDER);
508 if (rc != 0)
509 return EINVAL;
[a35b458]510
[4872160]511 /* Read length/literal and distance code length tables */
512 index = 0;
513 while (index < nlen + ndist) {
514 uint16_t symbol;
515 int err = huffman_decode(state, &dyn_len_code, &symbol);
516 if (err != EOK)
517 return EOK;
[a35b458]518
[4872160]519 if (symbol < 16) {
520 length[index] = symbol;
521 index++;
522 } else {
523 uint16_t len = 0;
[a35b458]524
[4872160]525 if (symbol == 16) {
526 if (index == 0)
527 return EINVAL;
[a35b458]528
[4872160]529 len = length[index - 1];
530 symbol = get_bits(state, 2) + 3;
531 CHECK_OVERRUN(*state);
532 } else if (symbol == 17) {
533 symbol = get_bits(state, 3) + 3;
534 CHECK_OVERRUN(*state);
535 } else {
536 symbol = get_bits(state, 7) + 11;
537 CHECK_OVERRUN(*state);
538 }
[a35b458]539
[4872160]540 if (index + symbol > nlen + ndist)
541 return EINVAL;
[a35b458]542
[4872160]543 while (symbol > 0) {
544 length[index] = len;
545 index++;
546 symbol--;
547 }
548 }
549 }
[a35b458]550
[4872160]551 /* Check for end-of-block code */
552 if (length[256] == 0)
553 return EINVAL;
[a35b458]554
[4872160]555 /* Build Huffman tables for literal/length codes */
556 rc = huffman_construct(&dyn_len_code, length, nlen);
557 if ((rc < 0) || ((rc > 0) && (dyn_len_code.count[0] + 1 != nlen)))
558 return EINVAL;
[a35b458]559
[4872160]560 /* Build Huffman tables for distance codes */
561 rc = huffman_construct(&dyn_dist_code, length + nlen, ndist);
562 if ((rc < 0) || ((rc > 0) && (dyn_dist_code.count[0] + 1 != ndist)))
563 return EINVAL;
[a35b458]564
[4872160]565 return inflate_codes(state, &dyn_len_code, &dyn_dist_code);
566}
567
568/** Inflate data
569 *
570 * @param src Source data buffer.
571 * @param srclen Source buffer size (bytes).
572 * @param dest Destination data buffer.
573 * @param destlen Destination buffer size (bytes).
574 *
575 * @return EOK on success.
576 * @return ENOENT on distance too large.
577 * @return EINVAL on invalid Huffman code or invalid deflate data.
578 * @return ELIMIT on input buffer overrun.
579 * @return ENOMEM on output buffer overrun.
580 *
581 */
[63a045c]582int inflate(const void *src, size_t srclen, void *dest, size_t destlen)
[4872160]583{
584 /* Initialize the state */
585 inflate_state_t state;
[a35b458]586
[4872160]587 state.dest = (uint8_t *) dest;
588 state.destlen = destlen;
589 state.destcnt = 0;
[a35b458]590
[63a045c]591 state.src = (const uint8_t *) src;
[4872160]592 state.srclen = srclen;
593 state.srccnt = 0;
[a35b458]594
[4872160]595 state.bitbuf = 0;
596 state.bitlen = 0;
[a35b458]597
[4872160]598 state.overrun = false;
[a35b458]599
[4872160]600 uint16_t last;
601 int ret = 0;
[a35b458]602
[4872160]603 do {
604 /* Last block is indicated by a non-zero bit */
605 last = get_bits(&state, 1);
606 CHECK_OVERRUN(state);
[a35b458]607
[4872160]608 /* Block type */
609 uint16_t type = get_bits(&state, 2);
610 CHECK_OVERRUN(state);
[a35b458]611
[4872160]612 switch (type) {
613 case 0:
614 ret = inflate_stored(&state);
615 break;
616 case 1:
617 ret = inflate_fixed(&state, &len_code, &dist_code);
618 break;
619 case 2:
620 ret = inflate_dynamic(&state);
621 break;
622 default:
623 ret = EINVAL;
624 }
625 } while ((!last) && (ret == 0));
[a35b458]626
[4872160]627 return ret;
628}
Note: See TracBrowser for help on using the repository browser.