1 /*-
2 * Copyright (c) 2014 Michihiro NAKAJIMA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "archive_platform.h"
27
28 __FBSDID("$FreeBSD$");
29
30 #ifdef HAVE_ERRNO_H
31 #include <errno.h>
32 #endif
33 #include <stdio.h>
34 #ifdef HAVE_STDLIB_H
35 #include <stdlib.h>
36 #endif
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #endif
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43 #ifdef HAVE_LZ4_H
44 #include <lz4.h>
45 #endif
46
47 #include "archive.h"
48 #include "archive_endian.h"
49 #include "archive_private.h"
50 #include "archive_read_private.h"
51 #include "archive_xxhash.h"
52
53 #define LZ4_MAGICNUMBER 0x184d2204
54 #define LZ4_SKIPPABLED 0x184d2a50
55 #define LZ4_LEGACY 0x184c2102
56
57 #if defined(HAVE_LIBLZ4)
58 struct private_data {
59 enum { SELECT_STREAM,
60 READ_DEFAULT_STREAM,
61 READ_DEFAULT_BLOCK,
62 READ_LEGACY_STREAM,
63 READ_LEGACY_BLOCK,
64 } stage;
65 struct {
66 unsigned block_independence:1;
67 unsigned block_checksum:3;
68 unsigned stream_size:1;
69 unsigned stream_checksum:1;
70 unsigned preset_dictionary:1;
71 int block_maximum_size;
72 } flags;
73 int64_t stream_size;
74 uint32_t dict_id;
75 char *out_block;
76 size_t out_block_size;
77
78 /* Bytes read but not yet consumed via __archive_read_consume() */
79 size_t unconsumed;
80 size_t decoded_size;
81 void *xxh32_state;
82
83 char valid; /* True = decompressor is initialized */
84 char eof; /* True = found end of compressed data. */
85 };
86
87 #define LEGACY_BLOCK_SIZE (8 * 1024 * 1024)
88
89 /* Lz4 filter */
90 static ssize_t lz4_filter_read(struct archive_read_filter *, const void **);
91 static int lz4_filter_close(struct archive_read_filter *);
92 #endif
93
94 /*
95 * Note that we can detect lz4 archives even if we can't decompress
96 * them. (In fact, we like detecting them because we can give better
97 * error messages.) So the bid framework here gets compiled even
98 * if liblz4 is unavailable.
99 */
100 static int lz4_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
101 static int lz4_reader_init(struct archive_read_filter *);
102 #if defined(HAVE_LIBLZ4)
103 static ssize_t lz4_filter_read_default_stream(struct archive_read_filter *,
104 const void **);
105 static ssize_t lz4_filter_read_legacy_stream(struct archive_read_filter *,
106 const void **);
107 #endif
108
109 static const struct archive_read_filter_bidder_vtable
110 lz4_bidder_vtable = {
111 .bid = lz4_reader_bid,
112 .init = lz4_reader_init,
113 };
114
115 int
archive_read_support_filter_lz4(struct archive * _a)116 archive_read_support_filter_lz4(struct archive *_a)
117 {
118 struct archive_read *a = (struct archive_read *)_a;
119
120 if (__archive_read_register_bidder(a, NULL, "lz4",
121 &lz4_bidder_vtable) != ARCHIVE_OK)
122 return (ARCHIVE_FATAL);
123
124 #if defined(HAVE_LIBLZ4)
125 return (ARCHIVE_OK);
126 #else
127 archive_set_error(_a, ARCHIVE_ERRNO_MISC,
128 "Using external lz4 program");
129 return (ARCHIVE_WARN);
130 #endif
131 }
132
133 /*
134 * Test whether we can handle this data.
135 *
136 * This logic returns zero if any part of the signature fails. It
137 * also tries to Do The Right Thing if a very short buffer prevents us
138 * from verifying as much as we would like.
139 */
140 static int
lz4_reader_bid(struct archive_read_filter_bidder * self,struct archive_read_filter * filter)141 lz4_reader_bid(struct archive_read_filter_bidder *self,
142 struct archive_read_filter *filter)
143 {
144 const unsigned char *buffer;
145 ssize_t avail;
146 int bits_checked;
147 uint32_t number;
148
149 (void)self; /* UNUSED */
150
151 /* Minimal lz4 archive is 11 bytes. */
152 buffer = __archive_read_filter_ahead(filter, 11, &avail);
153 if (buffer == NULL)
154 return (0);
155
156 /* First four bytes must be LZ4 magic numbers. */
157 bits_checked = 0;
158 if ((number = archive_le32dec(buffer)) == LZ4_MAGICNUMBER) {
159 unsigned char flag, BD;
160
161 bits_checked += 32;
162 /* Next follows a stream descriptor. */
163 /* Descriptor Flags. */
164 flag = buffer[4];
165 /* A version number must be "01". */
166 if (((flag & 0xc0) >> 6) != 1)
167 return (0);
168 /* A reserved bit must be "0". */
169 if (flag & 2)
170 return (0);
171 bits_checked += 8;
172 BD = buffer[5];
173 /* A block maximum size should be more than 3. */
174 if (((BD & 0x70) >> 4) < 4)
175 return (0);
176 /* Reserved bits must be "0". */
177 if (BD & ~0x70)
178 return (0);
179 bits_checked += 8;
180 } else if (number == LZ4_LEGACY) {
181 bits_checked += 32;
182 }
183
184 return (bits_checked);
185 }
186
187 #if !defined(HAVE_LIBLZ4)
188
189 /*
190 * If we don't have the library on this system, we can't actually do the
191 * decompression. We can, however, still detect compressed archives
192 * and emit a useful message.
193 */
194 static int
lz4_reader_init(struct archive_read_filter * self)195 lz4_reader_init(struct archive_read_filter *self)
196 {
197 int r;
198
199 r = __archive_read_program(self, "lz4 -d -q");
200 /* Note: We set the format here even if __archive_read_program()
201 * above fails. We do, after all, know what the format is
202 * even if we weren't able to read it. */
203 self->code = ARCHIVE_FILTER_LZ4;
204 self->name = "lz4";
205 return (r);
206 }
207
208
209 #else
210
211 static const struct archive_read_filter_vtable
212 lz4_reader_vtable = {
213 .read = lz4_filter_read,
214 .close = lz4_filter_close,
215 };
216
217 /*
218 * Setup the callbacks.
219 */
220 static int
lz4_reader_init(struct archive_read_filter * self)221 lz4_reader_init(struct archive_read_filter *self)
222 {
223 struct private_data *state;
224
225 self->code = ARCHIVE_FILTER_LZ4;
226 self->name = "lz4";
227
228 state = (struct private_data *)calloc(sizeof(*state), 1);
229 if (state == NULL) {
230 archive_set_error(&self->archive->archive, ENOMEM,
231 "Can't allocate data for lz4 decompression");
232 return (ARCHIVE_FATAL);
233 }
234
235 self->data = state;
236 state->stage = SELECT_STREAM;
237 self->vtable = &lz4_reader_vtable;
238
239 return (ARCHIVE_OK);
240 }
241
242 static int
lz4_allocate_out_block(struct archive_read_filter * self)243 lz4_allocate_out_block(struct archive_read_filter *self)
244 {
245 struct private_data *state = (struct private_data *)self->data;
246 size_t out_block_size = state->flags.block_maximum_size;
247 void *out_block;
248
249 if (!state->flags.block_independence)
250 out_block_size += 64 * 1024;
251 if (state->out_block_size < out_block_size) {
252 free(state->out_block);
253 out_block = (unsigned char *)malloc(out_block_size);
254 state->out_block_size = out_block_size;
255 if (out_block == NULL) {
256 archive_set_error(&self->archive->archive, ENOMEM,
257 "Can't allocate data for lz4 decompression");
258 return (ARCHIVE_FATAL);
259 }
260 state->out_block = out_block;
261 }
262 if (!state->flags.block_independence)
263 memset(state->out_block, 0, 64 * 1024);
264 return (ARCHIVE_OK);
265 }
266
267 static int
lz4_allocate_out_block_for_legacy(struct archive_read_filter * self)268 lz4_allocate_out_block_for_legacy(struct archive_read_filter *self)
269 {
270 struct private_data *state = (struct private_data *)self->data;
271 size_t out_block_size = LEGACY_BLOCK_SIZE;
272 void *out_block;
273
274 if (state->out_block_size < out_block_size) {
275 free(state->out_block);
276 out_block = (unsigned char *)malloc(out_block_size);
277 state->out_block_size = out_block_size;
278 if (out_block == NULL) {
279 archive_set_error(&self->archive->archive, ENOMEM,
280 "Can't allocate data for lz4 decompression");
281 return (ARCHIVE_FATAL);
282 }
283 state->out_block = out_block;
284 }
285 return (ARCHIVE_OK);
286 }
287
288 /*
289 * Return the next block of decompressed data.
290 */
291 static ssize_t
lz4_filter_read(struct archive_read_filter * self,const void ** p)292 lz4_filter_read(struct archive_read_filter *self, const void **p)
293 {
294 struct private_data *state = (struct private_data *)self->data;
295 ssize_t ret;
296
297 if (state->eof) {
298 *p = NULL;
299 return (0);
300 }
301
302 __archive_read_filter_consume(self->upstream, state->unconsumed);
303 state->unconsumed = 0;
304
305 switch (state->stage) {
306 case SELECT_STREAM:
307 break;
308 case READ_DEFAULT_STREAM:
309 case READ_LEGACY_STREAM:
310 /* Reading a lz4 stream already failed. */
311 archive_set_error(&self->archive->archive,
312 ARCHIVE_ERRNO_MISC, "Invalid sequence.");
313 return (ARCHIVE_FATAL);
314 case READ_DEFAULT_BLOCK:
315 ret = lz4_filter_read_default_stream(self, p);
316 if (ret != 0 || state->stage != SELECT_STREAM)
317 return ret;
318 break;
319 case READ_LEGACY_BLOCK:
320 ret = lz4_filter_read_legacy_stream(self, p);
321 if (ret != 0 || state->stage != SELECT_STREAM)
322 return ret;
323 break;
324 default:
325 archive_set_error(&self->archive->archive,
326 ARCHIVE_ERRNO_MISC, "Program error.");
327 return (ARCHIVE_FATAL);
328 break;
329 }
330
331 while (state->stage == SELECT_STREAM) {
332 const char *read_buf;
333
334 /* Read a magic number. */
335 read_buf = __archive_read_filter_ahead(self->upstream, 4,
336 NULL);
337 if (read_buf == NULL) {
338 state->eof = 1;
339 *p = NULL;
340 return (0);
341 }
342 uint32_t number = archive_le32dec(read_buf);
343 __archive_read_filter_consume(self->upstream, 4);
344 if (number == LZ4_MAGICNUMBER)
345 return lz4_filter_read_default_stream(self, p);
346 else if (number == LZ4_LEGACY)
347 return lz4_filter_read_legacy_stream(self, p);
348 else if ((number & ~0xF) == LZ4_SKIPPABLED) {
349 read_buf = __archive_read_filter_ahead(
350 self->upstream, 4, NULL);
351 if (read_buf == NULL) {
352 archive_set_error(
353 &self->archive->archive,
354 ARCHIVE_ERRNO_MISC,
355 "Malformed lz4 data");
356 return (ARCHIVE_FATAL);
357 }
358 uint32_t skip_bytes = archive_le32dec(read_buf);
359 __archive_read_filter_consume(self->upstream,
360 4 + skip_bytes);
361 } else {
362 /* Ignore following unrecognized data. */
363 state->eof = 1;
364 *p = NULL;
365 return (0);
366 }
367 }
368 state->eof = 1;
369 *p = NULL;
370 return (0);
371 }
372
373 static int
lz4_filter_read_descriptor(struct archive_read_filter * self)374 lz4_filter_read_descriptor(struct archive_read_filter *self)
375 {
376 struct private_data *state = (struct private_data *)self->data;
377 const char *read_buf;
378 ssize_t bytes_remaining;
379 ssize_t descriptor_bytes;
380 unsigned char flag, bd;
381 unsigned int chsum, chsum_verifier;
382
383 /* Make sure we have 2 bytes for flags. */
384 read_buf = __archive_read_filter_ahead(self->upstream, 2,
385 &bytes_remaining);
386 if (read_buf == NULL) {
387 archive_set_error(&self->archive->archive,
388 ARCHIVE_ERRNO_MISC,
389 "truncated lz4 input");
390 return (ARCHIVE_FATAL);
391 }
392
393 /*
394 Parse flags.
395 */
396 flag = (unsigned char)read_buf[0];
397 /* Verify version number. */
398 if ((flag & 0xc0) != 1<<6)
399 goto malformed_error;
400 /* A reserved bit must be zero. */
401 if (flag & 0x02)
402 goto malformed_error;
403 state->flags.block_independence = (flag & 0x20) != 0;
404 state->flags.block_checksum = (flag & 0x10)?4:0;
405 state->flags.stream_size = (flag & 0x08) != 0;
406 state->flags.stream_checksum = (flag & 0x04) != 0;
407 state->flags.preset_dictionary = (flag & 0x01) != 0;
408
409 /* BD */
410 bd = (unsigned char)read_buf[1];
411 /* Reserved bits must be zero. */
412 if (bd & 0x8f)
413 goto malformed_error;
414 /* Get a maximum block size. */
415 switch (read_buf[1] >> 4) {
416 case 4: /* 64 KB */
417 state->flags.block_maximum_size = 64 * 1024;
418 break;
419 case 5: /* 256 KB */
420 state->flags.block_maximum_size = 256 * 1024;
421 break;
422 case 6: /* 1 MB */
423 state->flags.block_maximum_size = 1024 * 1024;
424 break;
425 case 7: /* 4 MB */
426 state->flags.block_maximum_size = 4 * 1024 * 1024;
427 break;
428 default:
429 goto malformed_error;
430 }
431
432 /* Read the whole descriptor in a stream block. */
433 descriptor_bytes = 3;
434 if (state->flags.stream_size)
435 descriptor_bytes += 8;
436 if (state->flags.preset_dictionary)
437 descriptor_bytes += 4;
438 if (bytes_remaining < descriptor_bytes) {
439 read_buf = __archive_read_filter_ahead(self->upstream,
440 descriptor_bytes, &bytes_remaining);
441 if (read_buf == NULL) {
442 archive_set_error(&self->archive->archive,
443 ARCHIVE_ERRNO_MISC,
444 "truncated lz4 input");
445 return (ARCHIVE_FATAL);
446 }
447 }
448 /* Check if a descriptor is corrupted */
449 chsum = __archive_xxhash.XXH32(read_buf, (int)descriptor_bytes -1, 0);
450 chsum = (chsum >> 8) & 0xff;
451 chsum_verifier = read_buf[descriptor_bytes-1] & 0xff;
452 if (chsum != chsum_verifier)
453 goto malformed_error;
454
455 __archive_read_filter_consume(self->upstream, descriptor_bytes);
456
457 /* Make sure we have a large enough buffer for uncompressed data. */
458 if (lz4_allocate_out_block(self) != ARCHIVE_OK)
459 return (ARCHIVE_FATAL);
460 if (state->flags.stream_checksum)
461 state->xxh32_state = __archive_xxhash.XXH32_init(0);
462
463 state->decoded_size = 0;
464 /* Success */
465 return (ARCHIVE_OK);
466 malformed_error:
467 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
468 "malformed lz4 data");
469 return (ARCHIVE_FATAL);
470 }
471
472 static ssize_t
lz4_filter_read_data_block(struct archive_read_filter * self,const void ** p)473 lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
474 {
475 struct private_data *state = (struct private_data *)self->data;
476 ssize_t compressed_size;
477 const char *read_buf;
478 ssize_t bytes_remaining;
479 int checksum_size;
480 ssize_t uncompressed_size;
481 size_t prefix64k;
482
483 *p = NULL;
484
485 /* Make sure we have 4 bytes for a block size. */
486 read_buf = __archive_read_filter_ahead(self->upstream, 4,
487 &bytes_remaining);
488 if (read_buf == NULL)
489 goto truncated_error;
490 compressed_size = archive_le32dec(read_buf);
491 if ((compressed_size & 0x7fffffff) > state->flags.block_maximum_size)
492 goto malformed_error;
493 /* A compressed size == 0 means the end of stream blocks. */
494 if (compressed_size == 0) {
495 __archive_read_filter_consume(self->upstream, 4);
496 return 0;
497 }
498
499 checksum_size = state->flags.block_checksum;
500 /* Check if the block is uncompressed. */
501 if (compressed_size & 0x80000000U) {
502 compressed_size &= 0x7fffffff;
503 uncompressed_size = compressed_size;
504 } else
505 uncompressed_size = 0;/* Unknown yet. */
506
507 /*
508 Unfortunately, lz4 decompression API requires a whole block
509 for its decompression speed, so we read a whole block and allocate
510 a huge buffer used for decoded data.
511 */
512 read_buf = __archive_read_filter_ahead(self->upstream,
513 4 + compressed_size + checksum_size, &bytes_remaining);
514 if (read_buf == NULL)
515 goto truncated_error;
516
517 /* Optional processing, checking a block sum. */
518 if (checksum_size) {
519 unsigned int chsum = __archive_xxhash.XXH32(
520 read_buf + 4, (int)compressed_size, 0);
521 unsigned int chsum_block =
522 archive_le32dec(read_buf + 4 + compressed_size);
523 if (chsum != chsum_block)
524 goto malformed_error;
525 }
526
527
528 /* If the block is uncompressed, there is nothing to do. */
529 if (uncompressed_size) {
530 /* Prepare a prefix 64k block for next block. */
531 if (!state->flags.block_independence) {
532 prefix64k = 64 * 1024;
533 if (uncompressed_size < (ssize_t)prefix64k) {
534 memcpy(state->out_block
535 + prefix64k - uncompressed_size,
536 read_buf + 4,
537 uncompressed_size);
538 memset(state->out_block, 0,
539 prefix64k - uncompressed_size);
540 } else {
541 memcpy(state->out_block,
542 read_buf + 4
543 + uncompressed_size - prefix64k,
544 prefix64k);
545 }
546 state->decoded_size = 0;
547 }
548 state->unconsumed = 4 + uncompressed_size + checksum_size;
549 *p = read_buf + 4;
550 return uncompressed_size;
551 }
552
553 /*
554 Decompress a block data.
555 */
556 if (state->flags.block_independence) {
557 prefix64k = 0;
558 uncompressed_size = LZ4_decompress_safe(read_buf + 4,
559 state->out_block, (int)compressed_size,
560 state->flags.block_maximum_size);
561 } else {
562 prefix64k = 64 * 1024;
563 if (state->decoded_size) {
564 if (state->decoded_size < prefix64k) {
565 memmove(state->out_block
566 + prefix64k - state->decoded_size,
567 state->out_block + prefix64k,
568 state->decoded_size);
569 memset(state->out_block, 0,
570 prefix64k - state->decoded_size);
571 } else {
572 memmove(state->out_block,
573 state->out_block + state->decoded_size,
574 prefix64k);
575 }
576 }
577 #if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
578 uncompressed_size = LZ4_decompress_safe_usingDict(
579 read_buf + 4,
580 state->out_block + prefix64k, (int)compressed_size,
581 state->flags.block_maximum_size,
582 state->out_block,
583 prefix64k);
584 #else
585 uncompressed_size = LZ4_decompress_safe_withPrefix64k(
586 read_buf + 4,
587 state->out_block + prefix64k, (int)compressed_size,
588 state->flags.block_maximum_size);
589 #endif
590 }
591
592 /* Check if an error occurred in the decompression process. */
593 if (uncompressed_size < 0) {
594 archive_set_error(&(self->archive->archive),
595 ARCHIVE_ERRNO_MISC, "lz4 decompression failed");
596 return (ARCHIVE_FATAL);
597 }
598
599 state->unconsumed = 4 + compressed_size + checksum_size;
600 *p = state->out_block + prefix64k;
601 state->decoded_size = uncompressed_size;
602 return uncompressed_size;
603
604 malformed_error:
605 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
606 "malformed lz4 data");
607 return (ARCHIVE_FATAL);
608 truncated_error:
609 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
610 "truncated lz4 input");
611 return (ARCHIVE_FATAL);
612 }
613
614 static ssize_t
lz4_filter_read_default_stream(struct archive_read_filter * self,const void ** p)615 lz4_filter_read_default_stream(struct archive_read_filter *self, const void **p)
616 {
617 struct private_data *state = (struct private_data *)self->data;
618 const char *read_buf;
619 ssize_t bytes_remaining;
620 ssize_t ret;
621
622 if (state->stage == SELECT_STREAM) {
623 state->stage = READ_DEFAULT_STREAM;
624 /* First, read a descriptor. */
625 if((ret = lz4_filter_read_descriptor(self)) != ARCHIVE_OK)
626 return (ret);
627 state->stage = READ_DEFAULT_BLOCK;
628 }
629 /* Decompress a block. */
630 ret = lz4_filter_read_data_block(self, p);
631
632 /* If the end of block is detected, change the filter status
633 to read next stream. */
634 if (ret == 0 && *p == NULL)
635 state->stage = SELECT_STREAM;
636
637 /* Optional processing, checking a stream sum. */
638 if (state->flags.stream_checksum) {
639 if (state->stage == SELECT_STREAM) {
640 unsigned int checksum;
641 unsigned int checksum_stream;
642 read_buf = __archive_read_filter_ahead(self->upstream,
643 4, &bytes_remaining);
644 if (read_buf == NULL) {
645 archive_set_error(&self->archive->archive,
646 ARCHIVE_ERRNO_MISC, "truncated lz4 input");
647 return (ARCHIVE_FATAL);
648 }
649 checksum = archive_le32dec(read_buf);
650 __archive_read_filter_consume(self->upstream, 4);
651 checksum_stream = __archive_xxhash.XXH32_digest(
652 state->xxh32_state);
653 state->xxh32_state = NULL;
654 if (checksum != checksum_stream) {
655 archive_set_error(&self->archive->archive,
656 ARCHIVE_ERRNO_MISC,
657 "lz4 stream checksum error");
658 return (ARCHIVE_FATAL);
659 }
660 } else if (ret > 0)
661 __archive_xxhash.XXH32_update(state->xxh32_state,
662 *p, (int)ret);
663 }
664 return (ret);
665 }
666
667 static ssize_t
lz4_filter_read_legacy_stream(struct archive_read_filter * self,const void ** p)668 lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p)
669 {
670 struct private_data *state = (struct private_data *)self->data;
671 uint32_t compressed;
672 const char *read_buf;
673 ssize_t ret;
674
675 *p = NULL;
676 ret = lz4_allocate_out_block_for_legacy(self);
677 if (ret != ARCHIVE_OK)
678 return ret;
679
680 /* Make sure we have 4 bytes for a block size. */
681 read_buf = __archive_read_filter_ahead(self->upstream, 4, NULL);
682 if (read_buf == NULL) {
683 if (state->stage == SELECT_STREAM) {
684 state->stage = READ_LEGACY_STREAM;
685 archive_set_error(&self->archive->archive,
686 ARCHIVE_ERRNO_MISC,
687 "truncated lz4 input");
688 return (ARCHIVE_FATAL);
689 }
690 state->stage = SELECT_STREAM;
691 return 0;
692 }
693 state->stage = READ_LEGACY_BLOCK;
694 compressed = archive_le32dec(read_buf);
695 if (compressed > LZ4_COMPRESSBOUND(LEGACY_BLOCK_SIZE)) {
696 state->stage = SELECT_STREAM;
697 return 0;
698 }
699
700 /* Make sure we have a whole block. */
701 read_buf = __archive_read_filter_ahead(self->upstream,
702 4 + compressed, NULL);
703 if (read_buf == NULL) {
704 archive_set_error(&(self->archive->archive),
705 ARCHIVE_ERRNO_MISC, "truncated lz4 input");
706 return (ARCHIVE_FATAL);
707 }
708 ret = LZ4_decompress_safe(read_buf + 4, state->out_block,
709 compressed, (int)state->out_block_size);
710 if (ret < 0) {
711 archive_set_error(&(self->archive->archive),
712 ARCHIVE_ERRNO_MISC, "lz4 decompression failed");
713 return (ARCHIVE_FATAL);
714 }
715 *p = state->out_block;
716 state->unconsumed = 4 + compressed;
717 return ret;
718 }
719
720 /*
721 * Clean up the decompressor.
722 */
723 static int
lz4_filter_close(struct archive_read_filter * self)724 lz4_filter_close(struct archive_read_filter *self)
725 {
726 struct private_data *state;
727 int ret = ARCHIVE_OK;
728
729 state = (struct private_data *)self->data;
730 free(state->xxh32_state);
731 free(state->out_block);
732 free(state);
733 return (ret);
734 }
735
736 #endif /* HAVE_LIBLZ4 */
737