1 /*
2 zip_source_deflate.c -- deflate (de)compressoin routines
3 Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
4
5 This file is part of libzip, a library to manipulate ZIP archives.
6 The authors can be contacted at <libzip@nih.at>
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in
15 the documentation and/or other materials provided with the
16 distribution.
17 3. The names of the authors may not be used to endorse or promote
18 products derived from this software without specific prior
19 written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <limits.h>
37
38 #include "zipint.h"
39
40 struct deflate {
41 zip_error_t error;
42
43 bool eof;
44 bool can_store;
45 bool is_stored;
46 int mem_level;
47 zip_uint64_t size;
48 zip_uint8_t buffer[BUFSIZE];
49 z_stream zstr;
50 };
51
52 static zip_int64_t compress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
53 static zip_int64_t decompress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
54 static zip_int64_t deflate_compress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
55 static zip_int64_t deflate_decompress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
56 static void deflate_free(struct deflate *);
57
58
59 zip_source_t *
zip_source_deflate(zip_t * za,zip_source_t * src,zip_int32_t cm,int flags)60 zip_source_deflate(zip_t *za, zip_source_t *src, zip_int32_t cm, int flags)
61 {
62 struct deflate *ctx;
63 zip_source_t *s2;
64
65 if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
66 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
67 return NULL;
68 }
69
70 if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
71 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
72 return NULL;
73 }
74
75 zip_error_init(&ctx->error);
76 ctx->eof = false;
77 ctx->is_stored = false;
78 ctx->can_store = ZIP_CM_IS_DEFAULT(cm);
79 if (flags & ZIP_CODEC_ENCODE) {
80 ctx->mem_level = MAX_MEM_LEVEL;
81 }
82
83 if ((s2=zip_source_layered(za, src,
84 ((flags & ZIP_CODEC_ENCODE)
85 ? deflate_compress : deflate_decompress),
86 ctx)) == NULL) {
87 deflate_free(ctx);
88 return NULL;
89 }
90
91 return s2;
92 }
93
94
95 static zip_int64_t
compress_read(zip_source_t * src,struct deflate * ctx,void * data,zip_uint64_t len)96 compress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
97 {
98 int end, ret;
99 zip_int64_t n;
100 zip_uint64_t out_offset;
101 uInt out_len;
102
103 if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
104 return -1;
105
106 if (len == 0 || ctx->is_stored) {
107 return 0;
108 }
109
110 out_offset = 0;
111 out_len = (uInt)ZIP_MIN(UINT_MAX, len);
112 ctx->zstr.next_out = (Bytef *)data;
113 ctx->zstr.avail_out = out_len;
114
115 end = 0;
116 while (!end) {
117 ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
118
119 switch (ret) {
120 case Z_STREAM_END:
121 if (ctx->can_store && ctx->zstr.total_in <= ctx->zstr.total_out) {
122 ctx->is_stored = true;
123 ctx->size = ctx->zstr.total_in;
124 memcpy(data, ctx->buffer, ctx->size);
125 return (zip_int64_t)ctx->size;
126 }
127 /* fallthrough */
128 case Z_OK:
129 /* all ok */
130
131 if (ctx->zstr.avail_out == 0) {
132 out_offset += out_len;
133 if (out_offset < len) {
134 out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
135 ctx->zstr.next_out = (Bytef *)data+out_offset;
136 ctx->zstr.avail_out = out_len;
137 }
138 else {
139 ctx->can_store = false;
140 end = 1;
141 }
142 }
143 else if (ctx->eof && ctx->zstr.avail_in == 0)
144 end = 1;
145 break;
146
147 case Z_BUF_ERROR:
148 if (ctx->zstr.avail_in == 0) {
149 if (ctx->eof) {
150 end = 1;
151 break;
152 }
153
154 if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
155 _zip_error_set_from_source(&ctx->error, src);
156 end = 1;
157 break;
158 }
159 else if (n == 0) {
160 ctx->eof = true;
161 /* TODO: check against stat of src? */
162 ctx->size = ctx->zstr.total_in;
163 }
164 else {
165 if (ctx->zstr.total_in > 0) {
166 /* we overwrote a previously filled ctx->buffer */
167 ctx->can_store = false;
168 }
169 ctx->zstr.next_in = (Bytef *)ctx->buffer;
170 ctx->zstr.avail_in = (uInt)n;
171 }
172 continue;
173 }
174 /* fallthrough */
175 case Z_NEED_DICT:
176 case Z_DATA_ERROR:
177 case Z_STREAM_ERROR:
178 case Z_MEM_ERROR:
179 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
180
181 end = 1;
182 break;
183 }
184 }
185
186 if (ctx->zstr.avail_out < len) {
187 ctx->can_store = false;
188 return (zip_int64_t)(len - ctx->zstr.avail_out);
189 }
190
191 return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
192 }
193
194
195 static zip_int64_t
decompress_read(zip_source_t * src,struct deflate * ctx,void * data,zip_uint64_t len)196 decompress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
197 {
198 int end, ret;
199 zip_int64_t n;
200 zip_uint64_t out_offset;
201 uInt out_len;
202
203 if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
204 return -1;
205
206 if (len == 0)
207 return 0;
208
209 out_offset = 0;
210 out_len = (uInt)ZIP_MIN(UINT_MAX, len);
211 ctx->zstr.next_out = (Bytef *)data;
212 ctx->zstr.avail_out = out_len;
213
214 end = 0;
215 while (!end) {
216 ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
217
218 switch (ret) {
219 case Z_OK:
220 if (ctx->zstr.avail_out == 0) {
221 out_offset += out_len;
222 if (out_offset < len) {
223 out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
224 ctx->zstr.next_out = (Bytef *)data+out_offset;
225 ctx->zstr.avail_out = out_len;
226 }
227 else {
228 end = 1;
229 }
230 }
231 break;
232
233 case Z_STREAM_END:
234 ctx->eof = 1;
235 end = 1;
236 break;
237
238 case Z_BUF_ERROR:
239 if (ctx->zstr.avail_in == 0) {
240 if (ctx->eof) {
241 end = 1;
242 break;
243 }
244
245 if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
246 _zip_error_set_from_source(&ctx->error, src);
247 end = 1;
248 break;
249 }
250 else if (n == 0) {
251 ctx->eof = 1;
252 }
253 else {
254 ctx->zstr.next_in = (Bytef *)ctx->buffer;
255 ctx->zstr.avail_in = (uInt)n;
256 }
257 continue;
258 }
259 /* fallthrough */
260 case Z_NEED_DICT:
261 case Z_DATA_ERROR:
262 case Z_STREAM_ERROR:
263 case Z_MEM_ERROR:
264 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
265 end = 1;
266 break;
267 }
268 }
269
270 if (ctx->zstr.avail_out < len)
271 return (zip_int64_t)(len - ctx->zstr.avail_out);
272
273 return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
274 }
275
276
277 static zip_int64_t
deflate_compress(zip_source_t * src,void * ud,void * data,zip_uint64_t len,zip_source_cmd_t cmd)278 deflate_compress(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
279 {
280 struct deflate *ctx;
281 int ret;
282
283 ctx = (struct deflate *)ud;
284
285 switch (cmd) {
286 case ZIP_SOURCE_OPEN:
287 ctx->zstr.zalloc = Z_NULL;
288 ctx->zstr.zfree = Z_NULL;
289 ctx->zstr.opaque = NULL;
290 ctx->zstr.avail_in = 0;
291 ctx->zstr.next_in = NULL;
292 ctx->zstr.avail_out = 0;
293 ctx->zstr.next_out = NULL;
294
295 /* negative value to tell zlib not to write a header */
296 if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
297 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
298 return -1;
299 }
300
301 return 0;
302
303 case ZIP_SOURCE_READ:
304 return compress_read(src, ctx, data, len);
305
306 case ZIP_SOURCE_CLOSE:
307 deflateEnd(&ctx->zstr);
308 return 0;
309
310 case ZIP_SOURCE_STAT:
311 {
312 zip_stat_t *st;
313
314 st = (zip_stat_t *)data;
315
316 st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_DEFLATE;
317 st->valid |= ZIP_STAT_COMP_METHOD;
318 if (ctx->eof) {
319 st->comp_size = ctx->size;
320 st->valid |= ZIP_STAT_COMP_SIZE;
321 }
322 else
323 st->valid &= ~ZIP_STAT_COMP_SIZE;
324 }
325 return 0;
326
327 case ZIP_SOURCE_ERROR:
328 return zip_error_to_data(&ctx->error, data, len);
329
330 case ZIP_SOURCE_FREE:
331 deflate_free(ctx);
332 return 0;
333
334 case ZIP_SOURCE_SUPPORTS:
335 return ZIP_SOURCE_SUPPORTS_READABLE;
336
337 default:
338 zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
339 return -1;
340 }
341 }
342
343
344 static zip_int64_t
deflate_decompress(zip_source_t * src,void * ud,void * data,zip_uint64_t len,zip_source_cmd_t cmd)345 deflate_decompress(zip_source_t *src, void *ud, void *data,
346 zip_uint64_t len, zip_source_cmd_t cmd)
347 {
348 struct deflate *ctx;
349 zip_int64_t n;
350 int ret;
351
352 ctx = (struct deflate *)ud;
353
354 switch (cmd) {
355 case ZIP_SOURCE_OPEN:
356 if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
357 _zip_error_set_from_source(&ctx->error, src);
358 return -1;
359 }
360
361 ctx->zstr.zalloc = Z_NULL;
362 ctx->zstr.zfree = Z_NULL;
363 ctx->zstr.opaque = NULL;
364 ctx->zstr.next_in = (Bytef *)ctx->buffer;
365 ctx->zstr.avail_in = (uInt)n;
366
367 /* negative value to tell zlib that there is no header */
368 if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
369 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
370 return -1;
371 }
372 return 0;
373
374 case ZIP_SOURCE_READ:
375 return decompress_read(src, ctx, data, len);
376
377 case ZIP_SOURCE_CLOSE:
378 inflateEnd(&ctx->zstr);
379 return 0;
380
381 case ZIP_SOURCE_STAT:
382 {
383 zip_stat_t *st;
384
385 st = (zip_stat_t *)data;
386
387 st->comp_method = ZIP_CM_STORE;
388 if (st->comp_size > 0 && st->size > 0)
389 st->comp_size = st->size;
390
391 return 0;
392 }
393
394 case ZIP_SOURCE_ERROR:
395 return zip_error_to_data(&ctx->error, data, len);
396
397 case ZIP_SOURCE_FREE:
398 free(ctx);
399 return 0;
400
401 case ZIP_SOURCE_SUPPORTS:
402 return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
403
404 default:
405 zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
406 return -1;
407 }
408 }
409
410
411 static void
deflate_free(struct deflate * ctx)412 deflate_free(struct deflate *ctx)
413 {
414 free(ctx);
415 }
416