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#include "libbb.h"
28#include "archive.h"
29
30
31
32#define IBUFSIZ 2048
33
34
35#define OBUFSIZ 2048
36
37
38#define BIT_MASK 0x1f
39
40
41
42#define BLOCK_MODE 0x80
43
44
45
46#define FIRST 257
47#define CLEAR 256
48
49#define INIT_BITS 9
50
51
52
53#define HBITS 17
54#define HSIZE (1<<HBITS)
55#define HMASK (HSIZE-1)
56#define HPRIME 9941
57#define BITS 16
58#define BITS_STR "16"
59#undef MAXSEG_64K
60#define MAXCODE(n) (1L << (n))
61
62#define htabof(i) htab[i]
63#define codetabof(i) codetab[i]
64#define tab_prefixof(i) codetabof(i)
65#define tab_suffixof(i) ((unsigned char *)(htab))[i]
66#define de_stack ((unsigned char *)&(htab[HSIZE-1]))
67#define clear_tab_prefixof() memset(codetab, 0, 256)
68
69
70
71
72
73
74
75IF_DESKTOP(long long) int FAST_FUNC
76unpack_Z_stream(int fd_in, int fd_out)
77{
78 IF_DESKTOP(long long total_written = 0;)
79 IF_DESKTOP(long long) int retval = -1;
80 unsigned char *stackp;
81 long code;
82 int finchar;
83 long oldcode;
84 long incode;
85 int inbits;
86 int posbits;
87 int outpos;
88 int insize;
89 int bitmask;
90 long free_ent;
91 long maxcode;
92 long maxmaxcode;
93 int n_bits;
94 int rsize = 0;
95 unsigned char *inbuf;
96 unsigned char *outbuf;
97 unsigned char *htab;
98 unsigned short *codetab;
99
100
101
102 int maxbits;
103
104 int block_mode;
105
106 inbuf = xzalloc(IBUFSIZ + 64);
107 outbuf = xzalloc(OBUFSIZ + 2048);
108 htab = xzalloc(HSIZE);
109 codetab = xzalloc(HSIZE * sizeof(codetab[0]));
110
111 insize = 0;
112
113
114
115 if (full_read(fd_in, inbuf, 1) != 1) {
116 bb_error_msg("short read");
117 goto err;
118 }
119
120 maxbits = inbuf[0] & BIT_MASK;
121 block_mode = inbuf[0] & BLOCK_MODE;
122 maxmaxcode = MAXCODE(maxbits);
123
124 if (maxbits > BITS) {
125 bb_error_msg("compressed with %d bits, can only handle "
126 BITS_STR" bits", maxbits);
127 goto err;
128 }
129
130 n_bits = INIT_BITS;
131 maxcode = MAXCODE(INIT_BITS) - 1;
132 bitmask = (1 << INIT_BITS) - 1;
133 oldcode = -1;
134 finchar = 0;
135 outpos = 0;
136 posbits = 0 << 3;
137
138 free_ent = ((block_mode) ? FIRST : 256);
139
140
141
142
143 for (code = 255; code >= 0; --code) {
144 tab_suffixof(code) = (unsigned char) code;
145 }
146
147 do {
148 resetbuf:
149 {
150 int i;
151 int e;
152 int o;
153
154 o = posbits >> 3;
155 e = insize - o;
156
157 for (i = 0; i < e; ++i)
158 inbuf[i] = inbuf[i + o];
159
160 insize = e;
161 posbits = 0;
162 }
163
164 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
165 rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
166 if (rsize < 0)
167 bb_error_msg_and_die(bb_msg_read_error);
168 insize += rsize;
169 }
170
171 inbits = ((rsize > 0) ? (insize - insize % n_bits) << 3 :
172 (insize << 3) - (n_bits - 1));
173
174 while (inbits > posbits) {
175 if (free_ent > maxcode) {
176 posbits =
177 ((posbits - 1) +
178 ((n_bits << 3) -
179 (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
180 ++n_bits;
181 if (n_bits == maxbits) {
182 maxcode = maxmaxcode;
183 } else {
184 maxcode = MAXCODE(n_bits) - 1;
185 }
186 bitmask = (1 << n_bits) - 1;
187 goto resetbuf;
188 }
189 {
190 unsigned char *p = &inbuf[posbits >> 3];
191
192 code = ((((long) (p[0])) | ((long) (p[1]) << 8) |
193 ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask;
194 }
195 posbits += n_bits;
196
197
198 if (oldcode == -1) {
199 if (code >= 256)
200 bb_error_msg_and_die("corrupted data");
201 oldcode = code;
202 finchar = (int) oldcode;
203 outbuf[outpos++] = (unsigned char) finchar;
204 continue;
205 }
206
207 if (code == CLEAR && block_mode) {
208 clear_tab_prefixof();
209 free_ent = FIRST - 1;
210 posbits =
211 ((posbits - 1) +
212 ((n_bits << 3) -
213 (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
214 n_bits = INIT_BITS;
215 maxcode = MAXCODE(INIT_BITS) - 1;
216 bitmask = (1 << INIT_BITS) - 1;
217 goto resetbuf;
218 }
219
220 incode = code;
221 stackp = de_stack;
222
223
224 if (code >= free_ent) {
225 if (code > free_ent) {
226 unsigned char *p;
227
228 posbits -= n_bits;
229 p = &inbuf[posbits >> 3];
230
231 bb_error_msg
232 ("insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)",
233 insize, posbits, p[-1], p[0], p[1], p[2], p[3],
234 (posbits & 07));
235 bb_error_msg("corrupted data");
236 goto err;
237 }
238
239 *--stackp = (unsigned char) finchar;
240 code = oldcode;
241 }
242
243
244 while ((long) code >= (long) 256) {
245 if (stackp <= &htabof(0))
246 bb_error_msg_and_die("corrupted data");
247 *--stackp = tab_suffixof(code);
248 code = tab_prefixof(code);
249 }
250
251 finchar = tab_suffixof(code);
252 *--stackp = (unsigned char) finchar;
253
254
255 {
256 int i;
257
258 i = de_stack - stackp;
259 if (outpos + i >= OBUFSIZ) {
260 do {
261 if (i > OBUFSIZ - outpos) {
262 i = OBUFSIZ - outpos;
263 }
264
265 if (i > 0) {
266 memcpy(outbuf + outpos, stackp, i);
267 outpos += i;
268 }
269
270 if (outpos >= OBUFSIZ) {
271 xwrite(fd_out, outbuf, outpos);
272 IF_DESKTOP(total_written += outpos;)
273 outpos = 0;
274 }
275 stackp += i;
276 i = de_stack - stackp;
277 } while (i > 0);
278 } else {
279 memcpy(outbuf + outpos, stackp, i);
280 outpos += i;
281 }
282 }
283
284
285 code = free_ent;
286 if (code < maxmaxcode) {
287 tab_prefixof(code) = (unsigned short) oldcode;
288 tab_suffixof(code) = (unsigned char) finchar;
289 free_ent = code + 1;
290 }
291
292
293 oldcode = incode;
294 }
295
296 } while (rsize > 0);
297
298 if (outpos > 0) {
299 xwrite(fd_out, outbuf, outpos);
300 IF_DESKTOP(total_written += outpos;)
301 }
302
303 retval = IF_DESKTOP(total_written) + 0;
304 err:
305 free(inbuf);
306 free(outbuf);
307 free(htab);
308 free(codetab);
309 return retval;
310}
311