1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <setjmp.h>
37#include "libbb.h"
38#include "archive.h"
39
40typedef struct huft_t {
41 unsigned char e;
42 unsigned char b;
43 union {
44 unsigned short n;
45 struct huft_t *t;
46 } v;
47} huft_t;
48
49enum {
50
51
52 GUNZIP_WSIZE = 0x8000,
53
54 BMAX = 16,
55 N_MAX = 288,
56};
57
58
59
60
61
62
63
64
65
66
67#define STATE_IN_BSS 0
68#define STATE_IN_MALLOC 1
69
70
71typedef struct state_t {
72 off_t gunzip_bytes_out;
73 uint32_t gunzip_crc;
74
75 int gunzip_src_fd;
76 unsigned gunzip_outbuf_count;
77
78 unsigned char *gunzip_window;
79
80 uint32_t *gunzip_crc_table;
81
82
83 unsigned gunzip_bb;
84 unsigned char gunzip_bk;
85
86
87 unsigned char *bytebuffer;
88 off_t to_read;
89
90 unsigned bytebuffer_offset;
91 unsigned bytebuffer_size;
92
93
94 unsigned inflate_codes_ml;
95 unsigned inflate_codes_md;
96 unsigned inflate_codes_bb;
97 unsigned inflate_codes_k;
98 unsigned inflate_codes_w;
99 huft_t *inflate_codes_tl;
100 huft_t *inflate_codes_td;
101 unsigned inflate_codes_bl;
102 unsigned inflate_codes_bd;
103 unsigned inflate_codes_nn;
104 unsigned inflate_codes_dd;
105
106 smallint resume_copy;
107
108
109 smallint method;
110 smallint need_another_block;
111 smallint end_reached;
112
113
114 unsigned inflate_stored_n;
115 unsigned inflate_stored_b;
116 unsigned inflate_stored_k;
117 unsigned inflate_stored_w;
118
119 const char *error_msg;
120 jmp_buf error_jmp;
121} state_t;
122#define gunzip_bytes_out (S()gunzip_bytes_out )
123#define gunzip_crc (S()gunzip_crc )
124#define gunzip_src_fd (S()gunzip_src_fd )
125#define gunzip_outbuf_count (S()gunzip_outbuf_count)
126#define gunzip_window (S()gunzip_window )
127#define gunzip_crc_table (S()gunzip_crc_table )
128#define gunzip_bb (S()gunzip_bb )
129#define gunzip_bk (S()gunzip_bk )
130#define to_read (S()to_read )
131
132
133#define bytebuffer_max 0x4000
134#define bytebuffer (S()bytebuffer )
135#define bytebuffer_offset (S()bytebuffer_offset )
136#define bytebuffer_size (S()bytebuffer_size )
137#define inflate_codes_ml (S()inflate_codes_ml )
138#define inflate_codes_md (S()inflate_codes_md )
139#define inflate_codes_bb (S()inflate_codes_bb )
140#define inflate_codes_k (S()inflate_codes_k )
141#define inflate_codes_w (S()inflate_codes_w )
142#define inflate_codes_tl (S()inflate_codes_tl )
143#define inflate_codes_td (S()inflate_codes_td )
144#define inflate_codes_bl (S()inflate_codes_bl )
145#define inflate_codes_bd (S()inflate_codes_bd )
146#define inflate_codes_nn (S()inflate_codes_nn )
147#define inflate_codes_dd (S()inflate_codes_dd )
148#define resume_copy (S()resume_copy )
149#define method (S()method )
150#define need_another_block (S()need_another_block )
151#define end_reached (S()end_reached )
152#define inflate_stored_n (S()inflate_stored_n )
153#define inflate_stored_b (S()inflate_stored_b )
154#define inflate_stored_k (S()inflate_stored_k )
155#define inflate_stored_w (S()inflate_stored_w )
156#define error_msg (S()error_msg )
157#define error_jmp (S()error_jmp )
158
159
160#if STATE_IN_BSS
161#define DECLARE_STATE
162#define ALLOC_STATE
163#define DEALLOC_STATE ((void)0)
164#define S() state.
165#define PASS_STATE
166#define PASS_STATE_ONLY
167#define STATE_PARAM
168#define STATE_PARAM_ONLY void
169static state_t state;
170#endif
171
172#if STATE_IN_MALLOC
173#define DECLARE_STATE state_t *state
174#define ALLOC_STATE (state = xzalloc(sizeof(*state)))
175#define DEALLOC_STATE free(state)
176#define S() state->
177#define PASS_STATE state,
178#define PASS_STATE_ONLY state
179#define STATE_PARAM state_t *state,
180#define STATE_PARAM_ONLY state_t *state
181#endif
182
183
184static const uint16_t mask_bits[] ALIGN2 = {
185 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
186 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
187};
188
189
190static const uint16_t cplens[] ALIGN2 = {
191 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
192 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
193};
194
195
196
197static const uint8_t cplext[] ALIGN1 = {
198 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5,
199 5, 5, 5, 0, 99, 99
200};
201
202
203static const uint16_t cpdist[] ALIGN2 = {
204 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
205 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
206};
207
208
209static const uint8_t cpdext[] ALIGN1 = {
210 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
211 11, 11, 12, 12, 13, 13
212};
213
214
215
216static const uint8_t border[] ALIGN1 = {
217 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
218};
219
220
221
222
223
224
225
226
227static void huft_free(huft_t *p)
228{
229 huft_t *q;
230
231
232 while (p) {
233 q = (--p)->v.t;
234 free(p);
235 p = q;
236 }
237}
238
239static void huft_free_all(STATE_PARAM_ONLY)
240{
241 huft_free(inflate_codes_tl);
242 huft_free(inflate_codes_td);
243 inflate_codes_tl = NULL;
244 inflate_codes_td = NULL;
245}
246
247static void abort_unzip(STATE_PARAM_ONLY) NORETURN;
248static void abort_unzip(STATE_PARAM_ONLY)
249{
250 huft_free_all(PASS_STATE_ONLY);
251 longjmp(error_jmp, 1);
252}
253
254static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current, const unsigned required)
255{
256 while (*current < required) {
257 if (bytebuffer_offset >= bytebuffer_size) {
258 unsigned sz = bytebuffer_max - 4;
259 if (to_read >= 0 && to_read < sz)
260 sz = to_read;
261
262
263 bytebuffer_size = safe_read(gunzip_src_fd, &bytebuffer[4], sz);
264 if ((int)bytebuffer_size < 1) {
265 error_msg = "unexpected end of file";
266 abort_unzip(PASS_STATE_ONLY);
267 }
268 if (to_read >= 0)
269 to_read -= bytebuffer_size;
270 bytebuffer_size += 4;
271 bytebuffer_offset = 4;
272 }
273 bitbuffer |= ((unsigned) bytebuffer[bytebuffer_offset]) << *current;
274 bytebuffer_offset++;
275 *current += 8;
276 }
277 return bitbuffer;
278}
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295static int huft_build(const unsigned *b, const unsigned n,
296 const unsigned s, const unsigned short *d,
297 const unsigned char *e, huft_t **t, unsigned *m)
298{
299 unsigned a;
300 unsigned c[BMAX + 1];
301 unsigned eob_len;
302 unsigned f;
303 int g;
304 int htl;
305 unsigned i;
306 unsigned j;
307 int k;
308 unsigned *p;
309 huft_t *q;
310 huft_t r;
311 huft_t *u[BMAX];
312 unsigned v[N_MAX];
313 int ws[BMAX + 1];
314 int w;
315 unsigned x[BMAX + 1];
316 unsigned *xp;
317 int y;
318 unsigned z;
319
320
321 eob_len = n > 256 ? b[256] : BMAX;
322
323 *t = NULL;
324
325
326 memset(c, 0, sizeof(c));
327 p = (unsigned *) b;
328 i = n;
329 do {
330 c[*p]++;
331 p++;
332 } while (--i);
333 if (c[0] == n) {
334 *m = 0;
335 return 2;
336 }
337
338
339 for (j = 1; (c[j] == 0) && (j <= BMAX); j++)
340 continue;
341 k = j;
342 for (i = BMAX; (c[i] == 0) && i; i--)
343 continue;
344 g = i;
345 *m = (*m < j) ? j : ((*m > i) ? i : *m);
346
347
348 for (y = 1 << j; j < i; j++, y <<= 1) {
349 y -= c[j];
350 if (y < 0)
351 return 2;
352 }
353 y -= c[i];
354 if (y < 0)
355 return 2;
356 c[i] += y;
357
358
359 x[1] = j = 0;
360 p = c + 1;
361 xp = x + 2;
362 while (--i) {
363 j += *p++;
364 *xp++ = j;
365 }
366
367
368 p = (unsigned *) b;
369 i = 0;
370 do {
371 j = *p++;
372 if (j != 0) {
373 v[x[j]++] = i;
374 }
375 } while (++i < n);
376
377
378 x[0] = i = 0;
379 p = v;
380 htl = -1;
381 w = ws[0] = 0;
382 u[0] = NULL;
383 q = NULL;
384 z = 0;
385
386
387 for (; k <= g; k++) {
388 a = c[k];
389 while (a--) {
390
391
392 while (k > ws[htl + 1]) {
393 w = ws[++htl];
394
395
396 z = g - w;
397 z = z > *m ? *m : z;
398 j = k - w;
399 f = 1 << j;
400 if (f > a + 1) {
401
402 f -= a + 1;
403 xp = c + k;
404 while (++j < z) {
405 f <<= 1;
406 if (f <= *++xp) {
407 break;
408 }
409 f -= *xp;
410 }
411 }
412 j = (w + j > eob_len && w < eob_len) ? eob_len - w : j;
413 z = 1 << j;
414 ws[htl+1] = w + j;
415
416
417 q = xzalloc((z + 1) * sizeof(huft_t));
418 *t = q + 1;
419 t = &(q->v.t);
420 u[htl] = ++q;
421
422
423 if (htl) {
424 x[htl] = i;
425 r.b = (unsigned char) (w - ws[htl - 1]);
426 r.e = (unsigned char) (16 + j);
427 r.v.t = q;
428 j = (i & ((1 << w) - 1)) >> ws[htl - 1];
429 u[htl - 1][j] = r;
430 }
431 }
432
433
434 r.b = (unsigned char) (k - w);
435 if (p >= v + n) {
436 r.e = 99;
437 } else if (*p < s) {
438 r.e = (unsigned char) (*p < 256 ? 16 : 15);
439 r.v.n = (unsigned short) (*p++);
440 } else {
441 r.e = (unsigned char) e[*p - s];
442 r.v.n = d[*p++ - s];
443 }
444
445
446 f = 1 << (k - w);
447 for (j = i >> w; j < z; j += f) {
448 q[j] = r;
449 }
450
451
452 for (j = 1 << (k - 1); i & j; j >>= 1) {
453 i ^= j;
454 }
455 i ^= j;
456
457
458 while ((i & ((1 << w) - 1)) != x[htl]) {
459 w = ws[--htl];
460 }
461 }
462 }
463
464
465 *m = ws[1];
466
467
468 return y != 0 && g != 1;
469}
470
471
472
473
474
475
476
477
478
479
480
481
482#define ml inflate_codes_ml
483#define md inflate_codes_md
484#define bb inflate_codes_bb
485#define k inflate_codes_k
486#define w inflate_codes_w
487#define tl inflate_codes_tl
488#define td inflate_codes_td
489#define bl inflate_codes_bl
490#define bd inflate_codes_bd
491#define nn inflate_codes_nn
492#define dd inflate_codes_dd
493static void inflate_codes_setup(STATE_PARAM unsigned my_bl, unsigned my_bd)
494{
495 bl = my_bl;
496 bd = my_bd;
497
498 bb = gunzip_bb;
499 k = gunzip_bk;
500 w = gunzip_outbuf_count;
501
502 ml = mask_bits[bl];
503 md = mask_bits[bd];
504}
505
506static NOINLINE int inflate_codes(STATE_PARAM_ONLY)
507{
508 unsigned e;
509 huft_t *t;
510
511 if (resume_copy)
512 goto do_copy;
513
514 while (1) {
515 bb = fill_bitbuffer(PASS_STATE bb, &k, bl);
516 t = tl + ((unsigned) bb & ml);
517 e = t->e;
518 if (e > 16)
519 do {
520 if (e == 99)
521 abort_unzip(PASS_STATE_ONLY);;
522 bb >>= t->b;
523 k -= t->b;
524 e -= 16;
525 bb = fill_bitbuffer(PASS_STATE bb, &k, e);
526 t = t->v.t + ((unsigned) bb & mask_bits[e]);
527 e = t->e;
528 } while (e > 16);
529 bb >>= t->b;
530 k -= t->b;
531 if (e == 16) {
532 gunzip_window[w++] = (unsigned char) t->v.n;
533 if (w == GUNZIP_WSIZE) {
534 gunzip_outbuf_count = w;
535
536 w = 0;
537 return 1;
538 }
539 } else {
540
541 if (e == 15) {
542 break;
543 }
544
545
546 bb = fill_bitbuffer(PASS_STATE bb, &k, e);
547 nn = t->v.n + ((unsigned) bb & mask_bits[e]);
548 bb >>= e;
549 k -= e;
550
551
552 bb = fill_bitbuffer(PASS_STATE bb, &k, bd);
553 t = td + ((unsigned) bb & md);
554 e = t->e;
555 if (e > 16)
556 do {
557 if (e == 99)
558 abort_unzip(PASS_STATE_ONLY);
559 bb >>= t->b;
560 k -= t->b;
561 e -= 16;
562 bb = fill_bitbuffer(PASS_STATE bb, &k, e);
563 t = t->v.t + ((unsigned) bb & mask_bits[e]);
564 e = t->e;
565 } while (e > 16);
566 bb >>= t->b;
567 k -= t->b;
568 bb = fill_bitbuffer(PASS_STATE bb, &k, e);
569 dd = w - t->v.n - ((unsigned) bb & mask_bits[e]);
570 bb >>= e;
571 k -= e;
572
573
574 do_copy:
575 do {
576
577
578 unsigned delta;
579
580 dd &= GUNZIP_WSIZE - 1;
581 e = GUNZIP_WSIZE - (dd > w ? dd : w);
582 delta = w > dd ? w - dd : dd - w;
583 if (e > nn) e = nn;
584 nn -= e;
585
586
587 if (delta >= e) {
588 memcpy(gunzip_window + w, gunzip_window + dd, e);
589 w += e;
590 dd += e;
591 } else {
592
593
594 do {
595 gunzip_window[w++] = gunzip_window[dd++];
596 } while (--e);
597 }
598 if (w == GUNZIP_WSIZE) {
599 gunzip_outbuf_count = w;
600 resume_copy = (nn != 0);
601
602 w = 0;
603 return 1;
604 }
605 } while (nn);
606 resume_copy = 0;
607 }
608 }
609
610
611 gunzip_outbuf_count = w;
612 gunzip_bb = bb;
613 gunzip_bk = k;
614
615
616
617 huft_free_all(PASS_STATE_ONLY);
618
619
620 return 0;
621}
622#undef ml
623#undef md
624#undef bb
625#undef k
626#undef w
627#undef tl
628#undef td
629#undef bl
630#undef bd
631#undef nn
632#undef dd
633
634
635
636static void inflate_stored_setup(STATE_PARAM int my_n, int my_b, int my_k)
637{
638 inflate_stored_n = my_n;
639 inflate_stored_b = my_b;
640 inflate_stored_k = my_k;
641
642 inflate_stored_w = gunzip_outbuf_count;
643}
644
645static int inflate_stored(STATE_PARAM_ONLY)
646{
647
648 while (inflate_stored_n--) {
649 inflate_stored_b = fill_bitbuffer(PASS_STATE inflate_stored_b, &inflate_stored_k, 8);
650 gunzip_window[inflate_stored_w++] = (unsigned char) inflate_stored_b;
651 if (inflate_stored_w == GUNZIP_WSIZE) {
652 gunzip_outbuf_count = inflate_stored_w;
653
654 inflate_stored_w = 0;
655 inflate_stored_b >>= 8;
656 inflate_stored_k -= 8;
657 return 1;
658 }
659 inflate_stored_b >>= 8;
660 inflate_stored_k -= 8;
661 }
662
663
664 gunzip_outbuf_count = inflate_stored_w;
665 gunzip_bb = inflate_stored_b;
666 gunzip_bk = inflate_stored_k;
667 return 0;
668}
669
670
671
672
673
674
675
676
677
678
679static int inflate_block(STATE_PARAM smallint *e)
680{
681 unsigned ll[286 + 30];
682 unsigned t;
683 unsigned b;
684 unsigned k;
685
686
687
688 b = gunzip_bb;
689 k = gunzip_bk;
690
691
692 b = fill_bitbuffer(PASS_STATE b, &k, 1);
693 *e = b & 1;
694 b >>= 1;
695 k -= 1;
696
697
698 b = fill_bitbuffer(PASS_STATE b, &k, 2);
699 t = (unsigned) b & 3;
700 b >>= 2;
701 k -= 2;
702
703
704 gunzip_bb = b;
705 gunzip_bk = k;
706
707
708
709
710
711
712 switch (t) {
713 case 0:
714 {
715 unsigned n;
716 unsigned b_stored;
717 unsigned k_stored;
718
719
720 b_stored = gunzip_bb;
721 k_stored = gunzip_bk;
722
723
724 n = k_stored & 7;
725 b_stored >>= n;
726 k_stored -= n;
727
728
729 b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16);
730 n = ((unsigned) b_stored & 0xffff);
731 b_stored >>= 16;
732 k_stored -= 16;
733
734 b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16);
735 if (n != (unsigned) ((~b_stored) & 0xffff)) {
736 abort_unzip(PASS_STATE_ONLY);
737 }
738 b_stored >>= 16;
739 k_stored -= 16;
740
741 inflate_stored_setup(PASS_STATE n, b_stored, k_stored);
742
743 return -1;
744 }
745 case 1:
746
747
748
749
750 {
751 int i;
752 unsigned bl;
753 unsigned bd;
754
755
756
757
758 for (i = 0; i < 144; i++)
759 ll[i] = 8;
760 for (; i < 256; i++)
761 ll[i] = 9;
762 for (; i < 280; i++)
763 ll[i] = 7;
764 for (; i < 288; i++)
765 ll[i] = 8;
766 bl = 7;
767 huft_build(ll, 288, 257, cplens, cplext, &inflate_codes_tl, &bl);
768
769
770
771 for (i = 0; i < 30; i++)
772 ll[i] = 5;
773 bd = 5;
774 huft_build(ll, 30, 0, cpdist, cpdext, &inflate_codes_td, &bd);
775
776
777 inflate_codes_setup(PASS_STATE bl, bd);
778
779
780
781 return -2;
782 }
783 case 2:
784 {
785 enum { dbits = 6 };
786 enum { lbits = 9 };
787
788 huft_t *td;
789 unsigned i;
790 unsigned j;
791 unsigned l;
792 unsigned m;
793 unsigned n;
794 unsigned bl;
795 unsigned bd;
796 unsigned nb;
797 unsigned nl;
798 unsigned nd;
799
800
801 unsigned b_dynamic;
802 unsigned k_dynamic;
803
804
805 b_dynamic = gunzip_bb;
806 k_dynamic = gunzip_bk;
807
808
809 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5);
810 nl = 257 + ((unsigned) b_dynamic & 0x1f);
811
812 b_dynamic >>= 5;
813 k_dynamic -= 5;
814 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5);
815 nd = 1 + ((unsigned) b_dynamic & 0x1f);
816
817 b_dynamic >>= 5;
818 k_dynamic -= 5;
819 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 4);
820 nb = 4 + ((unsigned) b_dynamic & 0xf);
821
822 b_dynamic >>= 4;
823 k_dynamic -= 4;
824 if (nl > 286 || nd > 30)
825 abort_unzip(PASS_STATE_ONLY);
826
827
828 for (j = 0; j < nb; j++) {
829 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3);
830 ll[border[j]] = (unsigned) b_dynamic & 7;
831 b_dynamic >>= 3;
832 k_dynamic -= 3;
833 }
834 for (; j < 19; j++)
835 ll[border[j]] = 0;
836
837
838 bl = 7;
839 i = huft_build(ll, 19, 19, NULL, NULL, &inflate_codes_tl, &bl);
840 if (i != 0) {
841 abort_unzip(PASS_STATE_ONLY);
842 }
843
844
845 n = nl + nd;
846 m = mask_bits[bl];
847 i = l = 0;
848 while ((unsigned) i < n) {
849 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, (unsigned)bl);
850 td = inflate_codes_tl + ((unsigned) b_dynamic & m);
851 j = td->b;
852 b_dynamic >>= j;
853 k_dynamic -= j;
854 j = td->v.n;
855 if (j < 16) {
856 ll[i++] = l = j;
857 } else if (j == 16) {
858 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 2);
859 j = 3 + ((unsigned) b_dynamic & 3);
860 b_dynamic >>= 2;
861 k_dynamic -= 2;
862 if ((unsigned) i + j > n) {
863 abort_unzip(PASS_STATE_ONLY);
864 }
865 while (j--) {
866 ll[i++] = l;
867 }
868 } else if (j == 17) {
869 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3);
870 j = 3 + ((unsigned) b_dynamic & 7);
871 b_dynamic >>= 3;
872 k_dynamic -= 3;
873 if ((unsigned) i + j > n) {
874 abort_unzip(PASS_STATE_ONLY);
875 }
876 while (j--) {
877 ll[i++] = 0;
878 }
879 l = 0;
880 } else {
881 b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 7);
882 j = 11 + ((unsigned) b_dynamic & 0x7f);
883 b_dynamic >>= 7;
884 k_dynamic -= 7;
885 if ((unsigned) i + j > n) {
886 abort_unzip(PASS_STATE_ONLY);
887 }
888 while (j--) {
889 ll[i++] = 0;
890 }
891 l = 0;
892 }
893 }
894
895
896 huft_free(inflate_codes_tl);
897
898
899 gunzip_bb = b_dynamic;
900 gunzip_bk = k_dynamic;
901
902
903 bl = lbits;
904
905 i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl);
906 if (i != 0)
907 abort_unzip(PASS_STATE_ONLY);
908 bd = dbits;
909 i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd);
910 if (i != 0)
911 abort_unzip(PASS_STATE_ONLY);
912
913
914 inflate_codes_setup(PASS_STATE bl, bd);
915
916
917
918 return -2;
919 }
920 default:
921 abort_unzip(PASS_STATE_ONLY);
922 }
923}
924
925
926static void calculate_gunzip_crc(STATE_PARAM_ONLY)
927{
928 gunzip_crc = crc32_block_endian0(gunzip_crc, gunzip_window, gunzip_outbuf_count, gunzip_crc_table);
929 gunzip_bytes_out += gunzip_outbuf_count;
930}
931
932
933static int inflate_get_next_window(STATE_PARAM_ONLY)
934{
935 gunzip_outbuf_count = 0;
936
937 while (1) {
938 int ret;
939
940 if (need_another_block) {
941 if (end_reached) {
942 calculate_gunzip_crc(PASS_STATE_ONLY);
943 end_reached = 0;
944
945 return 0;
946 }
947 method = inflate_block(PASS_STATE &end_reached);
948 need_another_block = 0;
949 }
950
951 switch (method) {
952 case -1:
953 ret = inflate_stored(PASS_STATE_ONLY);
954 break;
955 case -2:
956 ret = inflate_codes(PASS_STATE_ONLY);
957 break;
958 default:
959 abort_unzip(PASS_STATE_ONLY);
960 }
961
962 if (ret == 1) {
963 calculate_gunzip_crc(PASS_STATE_ONLY);
964 return 1;
965 }
966 need_another_block = 1;
967 }
968
969}
970
971
972
973static IF_DESKTOP(long long) int
974inflate_unzip_internal(STATE_PARAM int in, int out)
975{
976 IF_DESKTOP(long long) int n = 0;
977 ssize_t nwrote;
978
979
980 gunzip_window = xmalloc(GUNZIP_WSIZE);
981 gunzip_outbuf_count = 0;
982 gunzip_bytes_out = 0;
983 gunzip_src_fd = in;
984
985
986 method = -1;
987 need_another_block = 1;
988 resume_copy = 0;
989 gunzip_bk = 0;
990 gunzip_bb = 0;
991
992
993 gunzip_crc_table = crc32_filltable(NULL, 0);
994 gunzip_crc = ~0;
995
996 error_msg = "corrupted data";
997 if (setjmp(error_jmp)) {
998
999 n = -1;
1000 goto ret;
1001 }
1002
1003 while (1) {
1004 int r = inflate_get_next_window(PASS_STATE_ONLY);
1005 nwrote = full_write(out, gunzip_window, gunzip_outbuf_count);
1006 if (nwrote != (ssize_t)gunzip_outbuf_count) {
1007 bb_perror_msg("write");
1008 n = -1;
1009 goto ret;
1010 }
1011 IF_DESKTOP(n += nwrote;)
1012 if (r == 0) break;
1013 }
1014
1015
1016 if (gunzip_bk >= 8) {
1017
1018
1019 bytebuffer_offset--;
1020 bytebuffer[bytebuffer_offset] = gunzip_bb & 0xff;
1021 gunzip_bb >>= 8;
1022 gunzip_bk -= 8;
1023 }
1024 ret:
1025
1026 free(gunzip_window);
1027 free(gunzip_crc_table);
1028 return n;
1029}
1030
1031
1032
1033
1034
1035
1036IF_DESKTOP(long long) int FAST_FUNC
1037inflate_unzip(inflate_unzip_result *res, off_t compr_size, int in, int out)
1038{
1039 IF_DESKTOP(long long) int n;
1040 DECLARE_STATE;
1041
1042 ALLOC_STATE;
1043
1044 to_read = compr_size;
1045
1046 bytebuffer_offset = 4;
1047 bytebuffer = xmalloc(bytebuffer_max);
1048 n = inflate_unzip_internal(PASS_STATE in, out);
1049 free(bytebuffer);
1050
1051 res->crc = gunzip_crc;
1052 res->bytes_out = gunzip_bytes_out;
1053 DEALLOC_STATE;
1054 return n;
1055}
1056
1057
1058
1059
1060
1061
1062
1063static int top_up(STATE_PARAM unsigned n)
1064{
1065 int count = bytebuffer_size - bytebuffer_offset;
1066
1067 if (count < (int)n) {
1068 memmove(bytebuffer, &bytebuffer[bytebuffer_offset], count);
1069 bytebuffer_offset = 0;
1070 bytebuffer_size = full_read(gunzip_src_fd, &bytebuffer[count], bytebuffer_max - count);
1071 if ((int)bytebuffer_size < 0) {
1072 bb_error_msg(bb_msg_read_error);
1073 return 0;
1074 }
1075 bytebuffer_size += count;
1076 if (bytebuffer_size < n)
1077 return 0;
1078 }
1079 return 1;
1080}
1081
1082static uint16_t buffer_read_le_u16(STATE_PARAM_ONLY)
1083{
1084 uint16_t res;
1085#if BB_LITTLE_ENDIAN
1086 move_from_unaligned16(res, &bytebuffer[bytebuffer_offset]);
1087#else
1088 res = bytebuffer[bytebuffer_offset];
1089 res |= bytebuffer[bytebuffer_offset + 1] << 8;
1090#endif
1091 bytebuffer_offset += 2;
1092 return res;
1093}
1094
1095static uint32_t buffer_read_le_u32(STATE_PARAM_ONLY)
1096{
1097 uint32_t res;
1098#if BB_LITTLE_ENDIAN
1099 move_from_unaligned32(res, &bytebuffer[bytebuffer_offset]);
1100#else
1101 res = bytebuffer[bytebuffer_offset];
1102 res |= bytebuffer[bytebuffer_offset + 1] << 8;
1103 res |= bytebuffer[bytebuffer_offset + 2] << 16;
1104 res |= bytebuffer[bytebuffer_offset + 3] << 24;
1105#endif
1106 bytebuffer_offset += 4;
1107 return res;
1108}
1109
1110static int check_header_gzip(STATE_PARAM unpack_info_t *info)
1111{
1112 union {
1113 unsigned char raw[8];
1114 struct {
1115 uint8_t gz_method;
1116 uint8_t flags;
1117 uint32_t mtime;
1118 uint8_t xtra_flags_UNUSED;
1119 uint8_t os_flags_UNUSED;
1120 } PACKED formatted;
1121 } header;
1122 struct BUG_header {
1123 char BUG_header[sizeof(header) == 8 ? 1 : -1];
1124 };
1125
1126
1127
1128
1129
1130 bytebuffer_size -= bytebuffer_offset;
1131 memmove(bytebuffer, &bytebuffer[bytebuffer_offset], bytebuffer_size);
1132 bytebuffer_offset = 0;
1133
1134 if (!top_up(PASS_STATE 8))
1135 return 0;
1136 memcpy(header.raw, &bytebuffer[bytebuffer_offset], 8);
1137 bytebuffer_offset += 8;
1138
1139
1140 if (header.formatted.gz_method != 8) {
1141 return 0;
1142 }
1143
1144 if (header.formatted.flags & 0x04) {
1145
1146 unsigned extra_short;
1147
1148 if (!top_up(PASS_STATE 2))
1149 return 0;
1150 extra_short = buffer_read_le_u16(PASS_STATE_ONLY);
1151 if (!top_up(PASS_STATE extra_short))
1152 return 0;
1153
1154 bytebuffer_offset += extra_short;
1155 }
1156
1157
1158
1159
1160 if (header.formatted.flags & 0x18) {
1161 while (1) {
1162 do {
1163 if (!top_up(PASS_STATE 1))
1164 return 0;
1165 } while (bytebuffer[bytebuffer_offset++] != 0);
1166 if ((header.formatted.flags & 0x18) != 0x18)
1167 break;
1168 header.formatted.flags &= ~0x18;
1169 }
1170 }
1171
1172 if (info)
1173 info->mtime = SWAP_LE32(header.formatted.mtime);
1174
1175
1176 if (header.formatted.flags & 0x02) {
1177 if (!top_up(PASS_STATE 2))
1178 return 0;
1179 bytebuffer_offset += 2;
1180 }
1181 return 1;
1182}
1183
1184IF_DESKTOP(long long) int FAST_FUNC
1185unpack_gz_stream_with_info(int in, int out, unpack_info_t *info)
1186{
1187 uint32_t v32;
1188 IF_DESKTOP(long long) int n;
1189 DECLARE_STATE;
1190
1191 n = 0;
1192
1193 ALLOC_STATE;
1194 to_read = -1;
1195
1196 bytebuffer = xmalloc(bytebuffer_max);
1197 gunzip_src_fd = in;
1198
1199 again:
1200 if (!check_header_gzip(PASS_STATE info)) {
1201 bb_error_msg("corrupted data");
1202 n = -1;
1203 goto ret;
1204 }
1205 n += inflate_unzip_internal(PASS_STATE in, out);
1206 if (n < 0)
1207 goto ret;
1208
1209 if (!top_up(PASS_STATE 8)) {
1210 bb_error_msg("corrupted data");
1211 n = -1;
1212 goto ret;
1213 }
1214
1215
1216 v32 = buffer_read_le_u32(PASS_STATE_ONLY);
1217 if ((~gunzip_crc) != v32) {
1218 bb_error_msg("crc error");
1219 n = -1;
1220 goto ret;
1221 }
1222
1223
1224 v32 = buffer_read_le_u32(PASS_STATE_ONLY);
1225 if ((uint32_t)gunzip_bytes_out != v32) {
1226 bb_error_msg("incorrect length");
1227 n = -1;
1228 }
1229
1230 if (!top_up(PASS_STATE 2))
1231 goto ret;
1232
1233 if (bytebuffer[bytebuffer_offset] == 0x1f
1234 && bytebuffer[bytebuffer_offset + 1] == 0x8b
1235 ) {
1236 bytebuffer_offset += 2;
1237 goto again;
1238 }
1239
1240
1241
1242 ret:
1243 free(bytebuffer);
1244 DEALLOC_STATE;
1245 return n;
1246}
1247
1248IF_DESKTOP(long long) int FAST_FUNC
1249unpack_gz_stream(int in, int out)
1250{
1251 return unpack_gz_stream_with_info(in, out, NULL);
1252}
1253