source: mainline/boot/generic/src/inflate.c@ d7f7a4a

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

Replace some license headers with SPDX identifier

Headers are replaced using tools/transorm-copyright.sh only
when it can be matched verbatim with the license header used
throughout most of the codebase.

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