]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/gzip/unlz.c
Add two missing eventhandler.h headers
[FreeBSD/FreeBSD.git] / usr.bin / gzip / unlz.c
1 /*      $NetBSD: unlz.c,v 1.6 2018/11/11 01:42:36 christos Exp $        */
2
3 /*-
4  * Copyright (c) 2018 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Christos Zoulas.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  */
33
34 /*  Lzd - Educational decompressor for the lzip format
35     Copyright (C) 2013-2018 Antonio Diaz Diaz.
36
37     This program is free software. Redistribution and use in source and
38     binary forms, with or without modification, are permitted provided
39     that the following conditions are met:
40
41     1. Redistributions of source code must retain the above copyright
42     notice, this list of conditions and the following disclaimer.
43
44     2. Redistributions in binary form must reproduce the above copyright
45     notice, this list of conditions and the following disclaimer in the
46     documentation and/or other materials provided with the distribution.
47
48     This program is distributed in the hope that it will be useful,
49     but WITHOUT ANY WARRANTY; without even the implied warranty of
50     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
51 */
52
53 #include <sys/param.h>
54 #include <stdio.h>
55 #include <string.h>
56 #include <stdlib.h>
57 #include <stdint.h>
58 #include <stdbool.h>
59 #include <errno.h>
60 #include <unistd.h>
61
62 #define LZ_STATES               12
63
64 #define LITERAL_CONTEXT_BITS    3
65 #define POS_STATE_BITS          2
66 #define POS_STATES              (1 << POS_STATE_BITS)
67 #define POS_STATE_MASK          (POS_STATES - 1)
68
69 #define STATES                  4
70 #define DIS_SLOT_BITS           6
71
72 #define DIS_MODEL_START         4
73 #define DIS_MODEL_END           14
74
75 #define MODELED_DISTANCES       (1 << (DIS_MODEL_END / 2))
76 #define DIS_ALIGN_BITS          4
77 #define DIS_ALIGN_SIZE          (1 << DIS_ALIGN_BITS)
78
79 #define LOW_BITS                3
80 #define MID_BITS                3
81 #define HIGH_BITS               8
82
83 #define LOW_SYMBOLS             (1 << LOW_BITS)
84 #define MID_SYMBOLS             (1 << MID_BITS)
85 #define HIGH_SYMBOLS            (1 << HIGH_BITS)
86
87 #define MAX_SYMBOLS             (LOW_SYMBOLS + MID_SYMBOLS + HIGH_SYMBOLS)
88
89 #define MIN_MATCH_LEN           2
90
91 #define BIT_MODEL_MOVE_BITS     5
92 #define BIT_MODEL_TOTAL_BITS    11
93 #define BIT_MODEL_TOTAL         (1 << BIT_MODEL_TOTAL_BITS)
94 #define BIT_MODEL_INIT          (BIT_MODEL_TOTAL / 2)
95
96 static const int lz_st_next[] = {
97         0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
98 };
99
100 static bool
101 lz_st_is_char(int st) {
102         return st < 7;
103 }
104
105 static int
106 lz_st_get_char(int st) {
107         return lz_st_next[st];
108 }
109
110 static int
111 lz_st_get_match(int st) {
112         return st < 7 ? 7 : 10;
113 }
114
115 static int
116 lz_st_get_rep(int st) {
117         return st < 7 ? 8 : 11;
118 }
119
120 static int
121 lz_st_get_short_rep(int st) {
122         return st < 7 ? 9 : 11;
123 }
124
125 struct lz_len_model {
126         int choice1;
127         int choice2;
128         int bm_low[POS_STATES][LOW_SYMBOLS];
129         int bm_mid[POS_STATES][MID_SYMBOLS];
130         int bm_high[HIGH_SYMBOLS];
131 };
132
133 static uint32_t lz_crc[256];
134
135 static void
136 lz_crc_init(void)
137 {
138         for (unsigned i = 0; i < nitems(lz_crc); i++) {
139                 unsigned c = i;
140                 for (unsigned j = 0; j < 8; j++) {
141                         if (c & 1)
142                                 c = 0xEDB88320U ^ (c >> 1);
143                         else
144                                 c >>= 1;
145                 }
146                 lz_crc[i] = c;
147       }
148 }
149
150 static void
151 lz_crc_update(uint32_t *crc, const uint8_t *buf, size_t len)
152 {
153         for (size_t i = 0; i < len; i++)
154                 *crc = lz_crc[(*crc ^ buf[i]) & 0xFF] ^ (*crc >> 8);
155 }
156
157 struct lz_range_decoder {
158         FILE *fp;
159         uint32_t code;
160         uint32_t range;
161 };
162
163 static int
164 lz_rd_create(struct lz_range_decoder *rd, FILE *fp)
165 {
166         rd->fp = fp;
167         rd->code = 0;
168         rd->range = ~0;
169         for (int i = 0; i < 5; i++)
170                 rd->code = (rd->code << 8) | (uint8_t)getc(rd->fp);
171         return ferror(rd->fp) ? -1 : 0;
172 }
173
174 static unsigned
175 lz_rd_decode(struct lz_range_decoder *rd, int num_bits)
176 {
177         unsigned symbol = 0;
178
179         for (int i = num_bits; i > 0; i--) {
180                 rd->range >>= 1;
181                 symbol <<= 1;
182                 if (rd->code >= rd->range) {
183                         rd->code -= rd->range;
184                         symbol |= 1;
185                 }
186                 if (rd->range <= 0x00FFFFFFU) {
187                         rd->range <<= 8; 
188                         rd->code = (rd->code << 8) | (uint8_t)getc(rd->fp);
189                 }
190         }
191
192         return symbol;
193 }
194
195 static unsigned
196 lz_rd_decode_bit(struct lz_range_decoder *rd, int *bm)
197 {
198         unsigned symbol;
199         const uint32_t bound = (rd->range >> BIT_MODEL_TOTAL_BITS) * *bm;
200
201         if(rd->code < bound) {
202                 rd->range = bound;
203                 *bm += (BIT_MODEL_TOTAL - *bm) >> BIT_MODEL_MOVE_BITS;
204                 symbol = 0;
205         }
206         else {
207                 rd->range -= bound;
208                 rd->code -= bound;
209                 *bm -= *bm >> BIT_MODEL_MOVE_BITS;
210                 symbol = 1;
211         }
212
213         if (rd->range <= 0x00FFFFFFU) {
214                 rd->range <<= 8;
215                 rd->code = (rd->code << 8) | (uint8_t)getc(rd->fp);
216         }
217         return symbol;
218 }
219
220 static unsigned
221 lz_rd_decode_tree(struct lz_range_decoder *rd, int *bm, int num_bits)
222 {
223         unsigned symbol = 1;
224
225         for (int i = 0; i < num_bits; i++)
226                 symbol = (symbol << 1) | lz_rd_decode_bit(rd, &bm[symbol]);
227
228         return symbol - (1 << num_bits);
229 }
230
231 static unsigned
232 lz_rd_decode_tree_reversed(struct lz_range_decoder *rd, int *bm, int num_bits)
233 {
234         unsigned symbol = lz_rd_decode_tree(rd, bm, num_bits);
235         unsigned reversed_symbol = 0;
236
237         for (int i = 0; i < num_bits; i++) {
238                 reversed_symbol = (reversed_symbol << 1) | (symbol & 1);
239                 symbol >>= 1;
240         }
241
242         return reversed_symbol;
243 }
244
245 static unsigned
246 lz_rd_decode_matched(struct lz_range_decoder *rd, int *bm, int match_byte)
247 {
248         unsigned symbol = 1;
249
250         for (int i = 7; i >= 0; i--) {
251                 const unsigned match_bit = (match_byte >> i) & 1;
252                 const unsigned bit = lz_rd_decode_bit(rd,
253                     &bm[symbol + (match_bit << 8) + 0x100]);
254                 symbol = (symbol << 1) | bit;
255                 if (match_bit != bit) {
256                         while (symbol < 0x100) {
257                                 symbol = (symbol << 1) |
258                                     lz_rd_decode_bit(rd, &bm[symbol]);
259                         }
260                         break;
261                 }
262         }
263         return symbol & 0xFF;
264 }
265
266 static unsigned
267 lz_rd_decode_len(struct lz_range_decoder *rd, struct lz_len_model *lm,
268     int pos_state)
269 {
270         if (lz_rd_decode_bit(rd, &lm->choice1) == 0)
271                 return lz_rd_decode_tree(rd, lm->bm_low[pos_state], LOW_BITS);
272
273         if (lz_rd_decode_bit(rd, &lm->choice2) == 0) {
274                 return LOW_SYMBOLS +
275                     lz_rd_decode_tree(rd, lm->bm_mid[pos_state], MID_BITS);
276         }
277
278         return LOW_SYMBOLS + MID_SYMBOLS +
279            lz_rd_decode_tree(rd, lm->bm_high, HIGH_BITS);
280 }
281
282 struct lz_decoder {
283         FILE *fin, *fout;
284         off_t pos, ppos, spos, dict_size;
285         bool wrapped;
286         uint32_t crc;
287         uint8_t *obuf;
288         struct lz_range_decoder rdec;
289 };
290
291 static int
292 lz_flush(struct lz_decoder *lz)
293 {
294         off_t offs = lz->pos - lz->spos;
295         if (offs <= 0)
296                 return -1;
297
298         size_t size = (size_t)offs;
299         lz_crc_update(&lz->crc, lz->obuf + lz->spos, size);
300         if (fwrite(lz->obuf + lz->spos, 1, size, lz->fout) != size)
301                 return -1;
302
303         lz->wrapped = lz->pos >= lz->dict_size;
304         if (lz->wrapped) {
305                 lz->ppos += lz->pos;
306                 lz->pos = 0;
307         }
308         lz->spos = lz->pos;
309         return 0;
310 }
311
312 static void
313 lz_destroy(struct lz_decoder *lz)
314 {
315         if (lz->fin)
316                 fclose(lz->fin);
317         if (lz->fout)
318                 fclose(lz->fout);
319         free(lz->obuf);
320 }
321
322 static int
323 lz_create(struct lz_decoder *lz, int fin, int fdout, int dict_size)
324 {
325         memset(lz, 0, sizeof(*lz));
326
327         lz->fin = fdopen(dup(fin), "r");
328         if (lz->fin == NULL)
329                 goto out;
330
331         lz->fout = fdopen(dup(fdout), "w");
332         if (lz->fout == NULL)
333                 goto out;
334
335         lz->pos = lz->ppos = lz->spos = 0;
336         lz->crc = ~0;
337         lz->dict_size = dict_size;
338         lz->wrapped = false;
339
340         lz->obuf = malloc(dict_size);
341         if (lz->obuf == NULL)
342                 goto out;
343
344         if (lz_rd_create(&lz->rdec, lz->fin) == -1)
345                 goto out;
346         return 0;
347 out:
348         lz_destroy(lz);
349         return -1;
350 }
351
352 static uint8_t
353 lz_peek(const struct lz_decoder *lz, unsigned ahead)
354 {
355         off_t diff = lz->pos - ahead - 1;
356
357         if (diff >= 0)
358                 return lz->obuf[diff];
359
360         if (lz->wrapped)
361                 return lz->obuf[lz->dict_size + diff];
362
363         return 0;
364 }
365
366 static void
367 lz_put(struct lz_decoder *lz, uint8_t b)
368 {
369         lz->obuf[lz->pos++] = b;
370         if (lz->dict_size == lz->pos)
371                 lz_flush(lz);
372 }
373
374 static off_t
375 lz_get_data_position(const struct lz_decoder *lz)
376 {
377         return lz->ppos + lz->pos;
378 }
379
380 static unsigned
381 lz_get_crc(const struct lz_decoder *lz)
382 {
383         return lz->crc ^ 0xffffffffU;
384 }
385
386 static void
387 lz_bm_init(int *a, size_t l)
388 {
389         for (size_t i = 0; i < l; i++)
390                 a[i] = BIT_MODEL_INIT;
391 }
392
393 #define LZ_BM_INIT(a)   lz_bm_init(a, nitems(a))
394 #define LZ_BM_INIT2(a)  do { \
395         size_t l = nitems(a[0]); \
396         for (size_t i = 0; i < nitems(a); i++) \
397                 lz_bm_init(a[i], l); \
398 } while (/*CONSTCOND*/0)
399
400 #define LZ_MODEL_INIT(a) do { \
401         a.choice1 = BIT_MODEL_INIT; \
402         a.choice2 = BIT_MODEL_INIT; \
403         LZ_BM_INIT2(a.bm_low); \
404         LZ_BM_INIT2(a.bm_mid); \
405         LZ_BM_INIT(a.bm_high); \
406 } while (/*CONSTCOND*/0)
407                 
408 static bool
409 lz_decode_member(struct lz_decoder *lz)
410 {
411         int bm_literal[1 << LITERAL_CONTEXT_BITS][0x300];
412         int bm_match[LZ_STATES][POS_STATES];
413         int bm_rep[4][LZ_STATES];
414         int bm_len[LZ_STATES][POS_STATES];
415         int bm_dis_slot[LZ_STATES][1 << DIS_SLOT_BITS];
416         int bm_dis[MODELED_DISTANCES - DIS_MODEL_END + 1];
417         int bm_align[DIS_ALIGN_SIZE];
418
419         LZ_BM_INIT2(bm_literal);
420         LZ_BM_INIT2(bm_match);
421         LZ_BM_INIT2(bm_rep);
422         LZ_BM_INIT2(bm_len);
423         LZ_BM_INIT2(bm_dis_slot);
424         LZ_BM_INIT(bm_dis);
425         LZ_BM_INIT(bm_align);
426
427         struct lz_len_model match_len_model;
428         struct lz_len_model rep_len_model;
429
430         LZ_MODEL_INIT(match_len_model);
431         LZ_MODEL_INIT(rep_len_model);
432
433         struct lz_range_decoder *rd = &lz->rdec;
434         unsigned rep[4] = { 0 };
435
436
437         int state = 0;
438
439         while (!feof(lz->fin) && !ferror(lz->fin)) {
440                 const int pos_state = lz_get_data_position(lz) & POS_STATE_MASK;
441                 // bit 1
442                 if (lz_rd_decode_bit(rd, &bm_match[state][pos_state]) == 0) {
443                         const uint8_t prev_byte = lz_peek(lz, 0);
444                         const int literal_state =
445                             prev_byte >> (8 - LITERAL_CONTEXT_BITS);
446                         int *bm = bm_literal[literal_state];
447                         if (lz_st_is_char(state))
448                                 lz_put(lz, lz_rd_decode_tree(rd, bm, 8));
449                         else {
450                                 int peek = lz_peek(lz, rep[0]);
451                                 lz_put(lz, lz_rd_decode_matched(rd, bm, peek));
452                         }
453                         state = lz_st_get_char(state);
454                         continue;
455                 }
456                 int len;
457                 // bit 2
458                 if (lz_rd_decode_bit(rd, &bm_rep[0][state]) != 0) {
459                         // bit 3
460                         if (lz_rd_decode_bit(rd, &bm_rep[1][state]) == 0) {
461                                 // bit 4
462                                 if (lz_rd_decode_bit(rd,
463                                     &bm_len[state][pos_state]) == 0)
464                                 {
465                                         state = lz_st_get_short_rep(state);
466                                         lz_put(lz, lz_peek(lz, rep[0]));
467                                         continue;
468                                 }
469                         } else {
470                                 unsigned distance;
471                                 // bit 4
472                                 if (lz_rd_decode_bit(rd, &bm_rep[2][state])
473                                     == 0)
474                                         distance = rep[1];
475                                 else {
476                                         // bit 5
477                                         if (lz_rd_decode_bit(rd,
478                                             &bm_rep[3][state]) == 0)
479                                                 distance = rep[2];
480                                         else {
481                                                 distance = rep[3];
482                                                 rep[3] = rep[2];
483                                         }
484                                         rep[2] = rep[1];
485                                 }
486                                 rep[1] = rep[0];
487                                 rep[0] = distance;
488                         }
489                         state = lz_st_get_rep(state);
490                         len = MIN_MATCH_LEN +
491                             lz_rd_decode_len(rd, &rep_len_model, pos_state);
492                 } else {
493                         rep[3] = rep[2]; rep[2] = rep[1]; rep[1] = rep[0];
494                         len = MIN_MATCH_LEN +
495                             lz_rd_decode_len(rd, &match_len_model, pos_state);
496                         const int len_state =
497                             MIN(len - MIN_MATCH_LEN, STATES - 1);
498                         rep[0] = lz_rd_decode_tree(rd, bm_dis_slot[len_state],
499                             DIS_SLOT_BITS);
500                         if (rep[0] >= DIS_MODEL_START) {
501                                 const unsigned dis_slot = rep[0];
502                                 const int direct_bits = (dis_slot >> 1) - 1;
503                                 rep[0] = (2 | (dis_slot & 1)) << direct_bits;
504                                 if (dis_slot < DIS_MODEL_END)
505                                         rep[0] += lz_rd_decode_tree_reversed(rd,
506                                             &bm_dis[rep[0] - dis_slot],
507                                             direct_bits);
508                                 else {
509                                         rep[0] += lz_rd_decode(rd, direct_bits
510                                             - DIS_ALIGN_BITS) << DIS_ALIGN_BITS;
511                                         rep[0] += lz_rd_decode_tree_reversed(rd,
512                                             bm_align, DIS_ALIGN_BITS);
513                                         if (rep[0] == 0xFFFFFFFFU) {
514                                                 lz_flush(lz);
515                                                 return len == MIN_MATCH_LEN;
516                                         }
517                                 }
518                         }
519                         state = lz_st_get_match(state);
520                         if (rep[0] >= lz->dict_size ||
521                             (rep[0] >= lz->pos && !lz->wrapped)) {
522                                 lz_flush(lz);
523                                 return false;
524                         }
525                 }
526                 for (int i = 0; i < len; i++)
527                         lz_put(lz, lz_peek(lz, rep[0]));
528         }
529         lz_flush(lz);
530         return false;
531 }
532
533 /*
534  * 0-3  CRC32 of the uncompressed data
535  * 4-11 size of the uncompressed data
536  * 12-19 member size including header and trailer
537  */
538 #define TRAILER_SIZE 20
539
540
541 static off_t
542 lz_decode(int fin, int fdout, unsigned dict_size, off_t *insize)
543 {
544         struct lz_decoder lz;
545         off_t rv = -1;
546
547         if (lz_create(&lz, fin, fdout, dict_size) == -1)
548                 return -1;
549
550         if (!lz_decode_member(&lz))
551                 goto out;
552
553         uint8_t trailer[TRAILER_SIZE];
554
555         for(size_t i = 0; i < nitems(trailer); i++) 
556                 trailer[i] = (uint8_t)getc(lz.fin);
557
558         unsigned crc = 0;
559         for (int i = 3; i >= 0; --i) {
560                 crc <<= 8;
561                 crc += trailer[i];
562         }
563
564         int64_t data_size = 0;
565         for (int i = 11; i >= 4; --i) {
566                 data_size <<= 8;
567                 data_size += trailer[i];
568         }
569
570         if (crc != lz_get_crc(&lz) || data_size != lz_get_data_position(&lz))
571                 goto out;
572
573         rv = 0;
574         for (int i = 19; i >= 12; --i) {
575                 rv <<= 8;
576                 rv += trailer[i];
577         }
578         if (insize)
579                 *insize = rv;
580 #if 0
581         /* Does not work with pipes */
582         rv = ftello(lz.fout);
583 #else
584         rv = data_size;
585 #endif
586 out:
587         lz_destroy(&lz);
588         return rv;
589 }
590
591
592 /*
593  * 0-3 magic
594  * 4 version
595  * 5 coded dict_size
596  */
597 #define HDR_SIZE 6
598 #define MIN_DICTIONARY_SIZE (1 << 12)
599 #define MAX_DICTIONARY_SIZE (1 << 29)
600
601 static const char hdrmagic[] = { 'L', 'Z', 'I', 'P', 1 };
602
603 static unsigned
604 lz_get_dict_size(unsigned char c)
605 {
606         unsigned dict_size = 1 << (c & 0x1f);
607         dict_size -= (dict_size >> 2) * ( (c >> 5) & 0x7);
608         if (dict_size < MIN_DICTIONARY_SIZE || dict_size > MAX_DICTIONARY_SIZE)
609                 return 0;
610         return dict_size;
611 }
612
613 static off_t
614 unlz(int fin, int fout, char *pre, size_t prelen, off_t *bytes_in)
615 {
616         if (lz_crc[0] == 0)
617                 lz_crc_init();
618
619         char header[HDR_SIZE];
620
621         if (prelen > sizeof(header))
622                 return -1;
623         if (pre && prelen)
624                 memcpy(header, pre, prelen);
625         
626         ssize_t nr = read(fin, header + prelen, sizeof(header) - prelen);
627         switch (nr) {
628         case -1:
629                 return -1;
630         case 0:
631                 return prelen ? -1 : 0;
632         default:
633                 if ((size_t)nr != sizeof(header) - prelen)
634                         return -1;
635                 break;
636         }
637
638         if (memcmp(header, hdrmagic, sizeof(hdrmagic)) != 0)
639                 return -1;
640
641         unsigned dict_size = lz_get_dict_size(header[5]);
642         if (dict_size == 0)
643                 return -1;
644
645         return lz_decode(fin, fout, dict_size, bytes_in);
646 }