diff options
Diffstat (limited to 'archival')
-rw-r--r-- | archival/libarchive/decompress_bunzip2.c | 78 | ||||
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 1 | ||||
-rw-r--r-- | archival/libarchive/decompress_unlzma.c | 11 | ||||
-rw-r--r-- | archival/lzop.c | 431 | ||||
-rw-r--r-- | archival/tar.c | 4 |
5 files changed, 280 insertions, 245 deletions
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index bec89edd3..7ef4e035f 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -100,7 +100,7 @@ struct bunzip_data { | |||
100 | unsigned dbufSize; | 100 | unsigned dbufSize; |
101 | 101 | ||
102 | /* For I/O error handling */ | 102 | /* For I/O error handling */ |
103 | jmp_buf jmpbuf; | 103 | jmp_buf *jmpbuf; |
104 | 104 | ||
105 | /* Big things go last (register-relative addressing can be larger for big offsets) */ | 105 | /* Big things go last (register-relative addressing can be larger for big offsets) */ |
106 | uint32_t crc32Table[256]; | 106 | uint32_t crc32Table[256]; |
@@ -127,7 +127,7 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |||
127 | /* if "no input fd" case: in_fd == -1, read fails, we jump */ | 127 | /* if "no input fd" case: in_fd == -1, read fails, we jump */ |
128 | bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE); | 128 | bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE); |
129 | if (bd->inbufCount <= 0) | 129 | if (bd->inbufCount <= 0) |
130 | longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); | 130 | longjmp(*bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); |
131 | bd->inbufPos = 0; | 131 | bd->inbufPos = 0; |
132 | } | 132 | } |
133 | 133 | ||
@@ -151,12 +151,12 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |||
151 | 151 | ||
152 | return bits; | 152 | return bits; |
153 | } | 153 | } |
154 | //#define get_bits(bd, n) (dbg("%d:get_bits()", __LINE__), get_bits(bd, n)) | ||
154 | 155 | ||
155 | /* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */ | 156 | /* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */ |
156 | static int get_next_block(bunzip_data *bd) | 157 | static int get_next_block(bunzip_data *bd) |
157 | { | 158 | { |
158 | struct group_data *hufGroup; | 159 | int groupCount, selector, |
159 | int groupCount, *base, *limit, selector, | ||
160 | i, j, symCount, symTotal, nSelectors, byteCount[256]; | 160 | i, j, symCount, symTotal, nSelectors, byteCount[256]; |
161 | uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; | 161 | uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; |
162 | uint32_t *dbuf; | 162 | uint32_t *dbuf; |
@@ -179,15 +179,19 @@ static int get_next_block(bunzip_data *bd) | |||
179 | i = get_bits(bd, 24); | 179 | i = get_bits(bd, 24); |
180 | j = get_bits(bd, 24); | 180 | j = get_bits(bd, 24); |
181 | bd->headerCRC = get_bits(bd, 32); | 181 | bd->headerCRC = get_bits(bd, 32); |
182 | if ((i == 0x177245) && (j == 0x385090)) return RETVAL_LAST_BLOCK; | 182 | if ((i == 0x177245) && (j == 0x385090)) |
183 | if ((i != 0x314159) || (j != 0x265359)) return RETVAL_NOT_BZIP_DATA; | 183 | return RETVAL_LAST_BLOCK; |
184 | if ((i != 0x314159) || (j != 0x265359)) | ||
185 | return RETVAL_NOT_BZIP_DATA; | ||
184 | 186 | ||
185 | /* We can add support for blockRandomised if anybody complains. There was | 187 | /* We can add support for blockRandomised if anybody complains. There was |
186 | some code for this in busybox 1.0.0-pre3, but nobody ever noticed that | 188 | some code for this in busybox 1.0.0-pre3, but nobody ever noticed that |
187 | it didn't actually work. */ | 189 | it didn't actually work. */ |
188 | if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT; | 190 | if (get_bits(bd, 1)) |
191 | return RETVAL_OBSOLETE_INPUT; | ||
189 | origPtr = get_bits(bd, 24); | 192 | origPtr = get_bits(bd, 24); |
190 | if (origPtr > bd->dbufSize) return RETVAL_DATA_ERROR; | 193 | if (origPtr > bd->dbufSize) |
194 | return RETVAL_DATA_ERROR; | ||
191 | 195 | ||
192 | /* mapping table: if some byte values are never used (encoding things | 196 | /* mapping table: if some byte values are never used (encoding things |
193 | like ascii text), the compression code removes the gaps to have fewer | 197 | like ascii text), the compression code removes the gaps to have fewer |
@@ -231,13 +235,21 @@ static int get_next_block(bunzip_data *bd) | |||
231 | /* Get next value */ | 235 | /* Get next value */ |
232 | int n = 0; | 236 | int n = 0; |
233 | while (get_bits(bd, 1)) { | 237 | while (get_bits(bd, 1)) { |
234 | if (n >= groupCount) return RETVAL_DATA_ERROR; | 238 | if (n >= groupCount) |
239 | return RETVAL_DATA_ERROR; | ||
235 | n++; | 240 | n++; |
236 | } | 241 | } |
237 | /* Decode MTF to get the next selector */ | 242 | /* Decode MTF to get the next selector */ |
238 | tmp_byte = mtfSymbol[n]; | 243 | tmp_byte = mtfSymbol[n]; |
239 | while (--n >= 0) | 244 | while (--n >= 0) |
240 | mtfSymbol[n + 1] = mtfSymbol[n]; | 245 | mtfSymbol[n + 1] = mtfSymbol[n]; |
246 | //We catch it later, in the second loop where we use selectors[i]. | ||
247 | //Maybe this is a better place, though? | ||
248 | // if (tmp_byte >= groupCount) { | ||
249 | // dbg("%d: selectors[%d]:%d groupCount:%d", | ||
250 | // __LINE__, i, tmp_byte, groupCount); | ||
251 | // return RETVAL_DATA_ERROR; | ||
252 | // } | ||
241 | mtfSymbol[0] = selectors[i] = tmp_byte; | 253 | mtfSymbol[0] = selectors[i] = tmp_byte; |
242 | } | 254 | } |
243 | 255 | ||
@@ -248,6 +260,8 @@ static int get_next_block(bunzip_data *bd) | |||
248 | uint8_t length[MAX_SYMBOLS]; | 260 | uint8_t length[MAX_SYMBOLS]; |
249 | /* 8 bits is ALMOST enough for temp[], see below */ | 261 | /* 8 bits is ALMOST enough for temp[], see below */ |
250 | unsigned temp[MAX_HUFCODE_BITS+1]; | 262 | unsigned temp[MAX_HUFCODE_BITS+1]; |
263 | struct group_data *hufGroup; | ||
264 | int *base, *limit; | ||
251 | int minLen, maxLen, pp, len_m1; | 265 | int minLen, maxLen, pp, len_m1; |
252 | 266 | ||
253 | /* Read Huffman code lengths for each symbol. They're stored in | 267 | /* Read Huffman code lengths for each symbol. They're stored in |
@@ -283,8 +297,10 @@ static int get_next_block(bunzip_data *bd) | |||
283 | /* Find largest and smallest lengths in this group */ | 297 | /* Find largest and smallest lengths in this group */ |
284 | minLen = maxLen = length[0]; | 298 | minLen = maxLen = length[0]; |
285 | for (i = 1; i < symCount; i++) { | 299 | for (i = 1; i < symCount; i++) { |
286 | if (length[i] > maxLen) maxLen = length[i]; | 300 | if (length[i] > maxLen) |
287 | else if (length[i] < minLen) minLen = length[i]; | 301 | maxLen = length[i]; |
302 | else if (length[i] < minLen) | ||
303 | minLen = length[i]; | ||
288 | } | 304 | } |
289 | 305 | ||
290 | /* Calculate permute[], base[], and limit[] tables from length[]. | 306 | /* Calculate permute[], base[], and limit[] tables from length[]. |
@@ -320,7 +336,8 @@ static int get_next_block(bunzip_data *bd) | |||
320 | /* Count symbols coded for at each bit length */ | 336 | /* Count symbols coded for at each bit length */ |
321 | /* NB: in pathological cases, temp[8] can end ip being 256. | 337 | /* NB: in pathological cases, temp[8] can end ip being 256. |
322 | * That's why uint8_t is too small for temp[]. */ | 338 | * That's why uint8_t is too small for temp[]. */ |
323 | for (i = 0; i < symCount; i++) temp[length[i]]++; | 339 | for (i = 0; i < symCount; i++) |
340 | temp[length[i]]++; | ||
324 | 341 | ||
325 | /* Calculate limit[] (the largest symbol-coding value at each bit | 342 | /* Calculate limit[] (the largest symbol-coding value at each bit |
326 | * length, which is (previous limit<<1)+symbols at this level), and | 343 | * length, which is (previous limit<<1)+symbols at this level), and |
@@ -363,12 +380,22 @@ static int get_next_block(bunzip_data *bd) | |||
363 | 380 | ||
364 | runPos = dbufCount = selector = 0; | 381 | runPos = dbufCount = selector = 0; |
365 | for (;;) { | 382 | for (;;) { |
383 | struct group_data *hufGroup; | ||
384 | int *base, *limit; | ||
366 | int nextSym; | 385 | int nextSym; |
386 | uint8_t ngrp; | ||
367 | 387 | ||
368 | /* Fetch next Huffman coding group from list. */ | 388 | /* Fetch next Huffman coding group from list. */ |
369 | symCount = GROUP_SIZE - 1; | 389 | symCount = GROUP_SIZE - 1; |
370 | if (selector >= nSelectors) return RETVAL_DATA_ERROR; | 390 | if (selector >= nSelectors) |
371 | hufGroup = bd->groups + selectors[selector++]; | 391 | return RETVAL_DATA_ERROR; |
392 | ngrp = selectors[selector++]; | ||
393 | if (ngrp >= groupCount) { | ||
394 | dbg("%d selectors[%d]:%d groupCount:%d", | ||
395 | __LINE__, selector-1, ngrp, groupCount); | ||
396 | return RETVAL_DATA_ERROR; | ||
397 | } | ||
398 | hufGroup = bd->groups + ngrp; | ||
372 | base = hufGroup->base - 1; | 399 | base = hufGroup->base - 1; |
373 | limit = hufGroup->limit - 1; | 400 | limit = hufGroup->limit - 1; |
374 | 401 | ||
@@ -403,7 +430,8 @@ static int get_next_block(bunzip_data *bd) | |||
403 | } | 430 | } |
404 | /* Figure how many bits are in next symbol and unget extras */ | 431 | /* Figure how many bits are in next symbol and unget extras */ |
405 | i = hufGroup->minLen; | 432 | i = hufGroup->minLen; |
406 | while (nextSym > limit[i]) ++i; | 433 | while (nextSym > limit[i]) |
434 | ++i; | ||
407 | j = hufGroup->maxLen - i; | 435 | j = hufGroup->maxLen - i; |
408 | if (j < 0) | 436 | if (j < 0) |
409 | return RETVAL_DATA_ERROR; | 437 | return RETVAL_DATA_ERROR; |
@@ -671,7 +699,10 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
671 | /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() | 699 | /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() |
672 | should work for NOFORK applets too, we must be extremely careful to not leak | 700 | should work for NOFORK applets too, we must be extremely careful to not leak |
673 | any allocations! */ | 701 | any allocations! */ |
674 | int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | 702 | int FAST_FUNC start_bunzip( |
703 | void *jmpbuf, | ||
704 | bunzip_data **bdp, | ||
705 | int in_fd, | ||
675 | const void *inbuf, int len) | 706 | const void *inbuf, int len) |
676 | { | 707 | { |
677 | bunzip_data *bd; | 708 | bunzip_data *bd; |
@@ -683,11 +714,14 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | |||
683 | 714 | ||
684 | /* Figure out how much data to allocate */ | 715 | /* Figure out how much data to allocate */ |
685 | i = sizeof(bunzip_data); | 716 | i = sizeof(bunzip_data); |
686 | if (in_fd != -1) i += IOBUF_SIZE; | 717 | if (in_fd != -1) |
718 | i += IOBUF_SIZE; | ||
687 | 719 | ||
688 | /* Allocate bunzip_data. Most fields initialize to zero. */ | 720 | /* Allocate bunzip_data. Most fields initialize to zero. */ |
689 | bd = *bdp = xzalloc(i); | 721 | bd = *bdp = xzalloc(i); |
690 | 722 | ||
723 | bd->jmpbuf = jmpbuf; | ||
724 | |||
691 | /* Setup input buffer */ | 725 | /* Setup input buffer */ |
692 | bd->in_fd = in_fd; | 726 | bd->in_fd = in_fd; |
693 | if (-1 == in_fd) { | 727 | if (-1 == in_fd) { |
@@ -702,10 +736,6 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | |||
702 | /* Init the CRC32 table (big endian) */ | 736 | /* Init the CRC32 table (big endian) */ |
703 | crc32_filltable(bd->crc32Table, 1); | 737 | crc32_filltable(bd->crc32Table, 1); |
704 | 738 | ||
705 | /* Setup for I/O error handling via longjmp */ | ||
706 | i = setjmp(bd->jmpbuf); | ||
707 | if (i) return i; | ||
708 | |||
709 | /* Ensure that file starts with "BZh['1'-'9']." */ | 739 | /* Ensure that file starts with "BZh['1'-'9']." */ |
710 | /* Update: now caller verifies 1st two bytes, makes .gz/.bz2 | 740 | /* Update: now caller verifies 1st two bytes, makes .gz/.bz2 |
711 | * integration easier */ | 741 | * integration easier */ |
@@ -752,8 +782,12 @@ unpack_bz2_stream(transformer_state_t *xstate) | |||
752 | outbuf = xmalloc(IOBUF_SIZE); | 782 | outbuf = xmalloc(IOBUF_SIZE); |
753 | len = 0; | 783 | len = 0; |
754 | while (1) { /* "Process one BZ... stream" loop */ | 784 | while (1) { /* "Process one BZ... stream" loop */ |
785 | jmp_buf jmpbuf; | ||
755 | 786 | ||
756 | i = start_bunzip(&bd, xstate->src_fd, outbuf + 2, len); | 787 | /* Setup for I/O error handling via longjmp */ |
788 | i = setjmp(jmpbuf); | ||
789 | if (i == 0) | ||
790 | i = start_bunzip(&jmpbuf, &bd, xstate->src_fd, outbuf + 2, len); | ||
757 | 791 | ||
758 | if (i == 0) { | 792 | if (i == 0) { |
759 | while (1) { /* "Produce some output bytes" loop */ | 793 | while (1) { /* "Produce some output bytes" loop */ |
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 7483a2cea..32fcb6b51 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -32,7 +32,6 @@ | |||
32 | * | 32 | * |
33 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 33 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
34 | */ | 34 | */ |
35 | #include <setjmp.h> | ||
36 | #include "libbb.h" | 35 | #include "libbb.h" |
37 | #include "bb_archive.h" | 36 | #include "bb_archive.h" |
38 | 37 | ||
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index be4342414..80a453806 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c | |||
@@ -11,6 +11,13 @@ | |||
11 | #include "libbb.h" | 11 | #include "libbb.h" |
12 | #include "bb_archive.h" | 12 | #include "bb_archive.h" |
13 | 13 | ||
14 | #if 0 | ||
15 | # define dbg(...) bb_error_msg(__VA_ARGS__) | ||
16 | #else | ||
17 | # define dbg(...) ((void)0) | ||
18 | #endif | ||
19 | |||
20 | |||
14 | #if ENABLE_FEATURE_LZMA_FAST | 21 | #if ENABLE_FEATURE_LZMA_FAST |
15 | # define speed_inline ALWAYS_INLINE | 22 | # define speed_inline ALWAYS_INLINE |
16 | # define size_inline | 23 | # define size_inline |
@@ -417,6 +424,10 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
417 | for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--) | 424 | for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--) |
418 | rep0 = (rep0 << 1) | rc_direct_bit(rc); | 425 | rep0 = (rep0 << 1) | rc_direct_bit(rc); |
419 | rep0 <<= LZMA_NUM_ALIGN_BITS; | 426 | rep0 <<= LZMA_NUM_ALIGN_BITS; |
427 | if ((int32_t)rep0 < 0) { | ||
428 | dbg("%d rep0:%d", __LINE__, rep0); | ||
429 | goto bad; | ||
430 | } | ||
420 | prob3 = p + LZMA_ALIGN; | 431 | prob3 = p + LZMA_ALIGN; |
421 | } | 432 | } |
422 | i2 = 1; | 433 | i2 = 1; |
diff --git a/archival/lzop.c b/archival/lzop.c index fef8cdba3..8f604254c 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -438,36 +438,33 @@ typedef struct chksum_t { | |||
438 | } chksum_t; | 438 | } chksum_t; |
439 | 439 | ||
440 | typedef struct header_t { | 440 | typedef struct header_t { |
441 | unsigned version; | 441 | /* used to have auxiliary fields here */ |
442 | unsigned lib_version; | 442 | |
443 | unsigned version_needed_to_extract; | 443 | /* Starting from here, the layout and endianness |
444 | uint32_t flags; | 444 | * are exactly in on-disk format. |
445 | uint32_t mode; | 445 | */ |
446 | uint32_t mtime; | 446 | uint16_t version_be16; |
447 | uint32_t gmtdiff; | 447 | uint16_t lib_version_be16; |
448 | uint32_t header_checksum; | 448 | uint16_t version_needed_to_extract_be16; |
449 | 449 | uint8_t method; | |
450 | uint32_t extra_field_len; | 450 | uint8_t level; |
451 | uint32_t extra_field_checksum; | 451 | uint32_t flags32; /* be32 on disk, but we keep this field in native order */ |
452 | 452 | uint32_t mode_be32; | |
453 | unsigned char method; | 453 | uint32_t mtime_be32; |
454 | unsigned char level; | 454 | uint32_t gmtdiff_be32; |
455 | 455 | char len_and_name[1+255+1]; | |
456 | /* info */ | ||
457 | char name[255+1]; | ||
458 | } header_t; | 456 | } header_t; |
459 | 457 | ||
460 | struct globals { | 458 | struct globals { |
461 | /*const uint32_t *lzo_crc32_table;*/ | 459 | /*const uint32_t *lzo_crc32_table;*/ |
462 | chksum_t chksum_in; | 460 | chksum_t chksum; |
463 | chksum_t chksum_out; | ||
464 | } FIX_ALIASING; | 461 | } FIX_ALIASING; |
465 | #define G (*(struct globals*)bb_common_bufsiz1) | 462 | #define G (*(struct globals*)bb_common_bufsiz1) |
466 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | ||
467 | //#define G (*ptr_to_globals) | 463 | //#define G (*ptr_to_globals) |
468 | //#define INIT_G() do { | 464 | #define INIT_G() do { \ |
469 | // SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); | 465 | setup_common_bufsiz(); \ |
470 | //} while (0) | 466 | /*SET_PTR_TO_GLOBALS(xzalloc(sizeof(G)));*/ \ |
467 | } while (0) | ||
471 | 468 | ||
472 | 469 | ||
473 | /**********************************************************************/ | 470 | /**********************************************************************/ |
@@ -548,24 +545,24 @@ lzo_crc32(uint32_t c, const uint8_t* buf, unsigned len) | |||
548 | } | 545 | } |
549 | 546 | ||
550 | /**********************************************************************/ | 547 | /**********************************************************************/ |
551 | static void init_chksum(chksum_t *ct) | 548 | static void init_chksum(void) |
552 | { | 549 | { |
553 | ct->f_adler32 = ADLER32_INIT_VALUE; | 550 | G.chksum.f_adler32 = ADLER32_INIT_VALUE; |
554 | ct->f_crc32 = CRC32_INIT_VALUE; | 551 | G.chksum.f_crc32 = CRC32_INIT_VALUE; |
555 | } | 552 | } |
556 | 553 | ||
557 | static void add_bytes_to_chksum(chksum_t *ct, const void* buf, int cnt) | 554 | static void add_bytes_to_chksum(const void* buf, int cnt) |
558 | { | 555 | { |
559 | /* We need to handle the two checksums at once, because at the | 556 | /* We need to handle the two checksums at once, because at the |
560 | * beginning of the header, we don't know yet which one we'll | 557 | * beginning of the header, we don't know yet which one we'll |
561 | * eventually need */ | 558 | * eventually need */ |
562 | ct->f_adler32 = lzo_adler32(ct->f_adler32, (const uint8_t*)buf, cnt); | 559 | G.chksum.f_adler32 = lzo_adler32(G.chksum.f_adler32, (const uint8_t*)buf, cnt); |
563 | ct->f_crc32 = lzo_crc32(ct->f_crc32, (const uint8_t*)buf, cnt); | 560 | G.chksum.f_crc32 = lzo_crc32(G.chksum.f_crc32, (const uint8_t*)buf, cnt); |
564 | } | 561 | } |
565 | 562 | ||
566 | static uint32_t chksum_getresult(chksum_t *ct, const header_t *h) | 563 | static uint32_t chksum_getresult(uint32_t h_flags32) |
567 | { | 564 | { |
568 | return (h->flags & F_H_CRC32) ? ct->f_crc32 : ct->f_adler32; | 565 | return (h_flags32 & F_H_CRC32) ? G.chksum.f_crc32 : G.chksum.f_adler32; |
569 | } | 566 | } |
570 | 567 | ||
571 | /**********************************************************************/ | 568 | /**********************************************************************/ |
@@ -575,50 +572,23 @@ static uint32_t read32(void) | |||
575 | xread(0, &v, 4); | 572 | xread(0, &v, 4); |
576 | return ntohl(v); | 573 | return ntohl(v); |
577 | } | 574 | } |
578 | |||
579 | static void write32(uint32_t v) | ||
580 | { | ||
581 | v = htonl(v); | ||
582 | xwrite(1, &v, 4); | ||
583 | } | ||
584 | |||
585 | static void f_write(const void* buf, int cnt) | ||
586 | { | ||
587 | xwrite(1, buf, cnt); | ||
588 | add_bytes_to_chksum(&G.chksum_out, buf, cnt); | ||
589 | } | ||
590 | |||
591 | static void f_read(void* buf, int cnt) | 575 | static void f_read(void* buf, int cnt) |
592 | { | 576 | { |
593 | xread(0, buf, cnt); | 577 | xread(0, buf, cnt); |
594 | add_bytes_to_chksum(&G.chksum_in, buf, cnt); | 578 | add_bytes_to_chksum(buf, cnt); |
595 | } | 579 | } |
596 | 580 | //static int f_read8(void) | |
597 | static int f_read8(void) | 581 | //{ |
598 | { | 582 | // uint8_t v; |
599 | uint8_t v; | 583 | // f_read(&v, 1); |
600 | f_read(&v, 1); | 584 | // return v; |
601 | return v; | 585 | //} |
602 | } | 586 | //static unsigned f_read16(void) |
603 | 587 | //{ | |
604 | static void f_write8(uint8_t v) | 588 | // uint16_t v; |
605 | { | 589 | // f_read(&v, 2); |
606 | f_write(&v, 1); | 590 | // return ntohs(v); |
607 | } | 591 | //} |
608 | |||
609 | static unsigned f_read16(void) | ||
610 | { | ||
611 | uint16_t v; | ||
612 | f_read(&v, 2); | ||
613 | return ntohs(v); | ||
614 | } | ||
615 | |||
616 | static void f_write16(uint16_t v) | ||
617 | { | ||
618 | v = htons(v); | ||
619 | f_write(&v, 2); | ||
620 | } | ||
621 | |||
622 | static uint32_t f_read32(void) | 592 | static uint32_t f_read32(void) |
623 | { | 593 | { |
624 | uint32_t v; | 594 | uint32_t v; |
@@ -626,34 +596,30 @@ static uint32_t f_read32(void) | |||
626 | return ntohl(v); | 596 | return ntohl(v); |
627 | } | 597 | } |
628 | 598 | ||
629 | static void f_write32(uint32_t v) | 599 | static void write32(uint32_t v) |
630 | { | 600 | { |
631 | v = htonl(v); | 601 | v = htonl(v); |
632 | f_write(&v, 4); | 602 | xwrite(1, &v, 4); |
633 | } | 603 | } |
634 | 604 | static void f_write(const void* buf, int cnt) | |
635 | /**********************************************************************/ | ||
636 | static int lzo_get_method(header_t *h) | ||
637 | { | 605 | { |
638 | /* check method */ | 606 | xwrite(1, buf, cnt); |
639 | if (h->method == M_LZO1X_1) { | 607 | add_bytes_to_chksum(buf, cnt); |
640 | if (h->level == 0) | ||
641 | h->level = 3; | ||
642 | } else if (h->method == M_LZO1X_1_15) { | ||
643 | if (h->level == 0) | ||
644 | h->level = 1; | ||
645 | } else if (h->method == M_LZO1X_999) { | ||
646 | if (h->level == 0) | ||
647 | h->level = 9; | ||
648 | } else | ||
649 | return -1; /* not a LZO method */ | ||
650 | |||
651 | /* check compression level */ | ||
652 | if (h->level < 1 || h->level > 9) | ||
653 | return 15; | ||
654 | |||
655 | return 0; | ||
656 | } | 608 | } |
609 | //static void f_write8(uint8_t v) | ||
610 | //{ | ||
611 | // f_write(&v, 1); | ||
612 | //} | ||
613 | //static void f_write16(uint16_t v) | ||
614 | //{ | ||
615 | // v = htons(v); | ||
616 | // f_write(&v, 2); | ||
617 | //} | ||
618 | //static void f_write32(uint32_t v) | ||
619 | //{ | ||
620 | // v = htonl(v); | ||
621 | // f_write(&v, 4); | ||
622 | //} | ||
657 | 623 | ||
658 | /**********************************************************************/ | 624 | /**********************************************************************/ |
659 | #define LZO_BLOCK_SIZE (256 * 1024l) | 625 | #define LZO_BLOCK_SIZE (256 * 1024l) |
@@ -671,52 +637,61 @@ static NOINLINE int lzo_compress(const header_t *h) | |||
671 | int r = 0; /* LZO_E_OK */ | 637 | int r = 0; /* LZO_E_OK */ |
672 | uint8_t *const b1 = xzalloc(block_size); | 638 | uint8_t *const b1 = xzalloc(block_size); |
673 | uint8_t *const b2 = xzalloc(MAX_COMPRESSED_SIZE(block_size)); | 639 | uint8_t *const b2 = xzalloc(MAX_COMPRESSED_SIZE(block_size)); |
674 | unsigned src_len = 0, dst_len = 0; | ||
675 | uint32_t d_adler32 = ADLER32_INIT_VALUE; | 640 | uint32_t d_adler32 = ADLER32_INIT_VALUE; |
676 | uint32_t d_crc32 = CRC32_INIT_VALUE; | 641 | uint32_t d_crc32 = CRC32_INIT_VALUE; |
677 | int l; | ||
678 | uint8_t *wrk_mem = NULL; | 642 | uint8_t *wrk_mem = NULL; |
679 | 643 | ||
644 | /* Only these methods are possible, see lzo_set_method(): | ||
645 | * -1: M_LZO1X_1_15 | ||
646 | * -2..6: M_LZO1X_1 | ||
647 | * -7..9: M_LZO1X_999 if ENABLE_LZOP_COMPR_HIGH | ||
648 | */ | ||
680 | if (h->method == M_LZO1X_1) | 649 | if (h->method == M_LZO1X_1) |
681 | wrk_mem = xzalloc(LZO1X_1_MEM_COMPRESS); | 650 | wrk_mem = xzalloc(LZO1X_1_MEM_COMPRESS); |
682 | else if (h->method == M_LZO1X_1_15) | 651 | else /* check only if it's not the only possibility */ |
683 | wrk_mem = xzalloc(LZO1X_1_15_MEM_COMPRESS); | 652 | IF_LZOP_COMPR_HIGH(if (h->method == M_LZO1X_1_15)) |
684 | else if (h->method == M_LZO1X_999) | 653 | wrk_mem = xzalloc(LZO1X_1_15_MEM_COMPRESS); |
654 | #if ENABLE_LZOP_COMPR_HIGH | ||
655 | else /* must be h->method == M_LZO1X_999 */ | ||
685 | wrk_mem = xzalloc(LZO1X_999_MEM_COMPRESS); | 656 | wrk_mem = xzalloc(LZO1X_999_MEM_COMPRESS); |
657 | #endif | ||
686 | 658 | ||
687 | for (;;) { | 659 | for (;;) { |
660 | unsigned src_len, dst_len; | ||
661 | int l; | ||
662 | uint32_t wordbuf[6]; | ||
663 | uint32_t *wordptr = wordbuf; | ||
664 | |||
688 | /* read a block */ | 665 | /* read a block */ |
689 | l = full_read(0, b1, block_size); | 666 | l = full_read(0, b1, block_size); |
690 | src_len = (l > 0 ? l : 0); | 667 | src_len = (l > 0 ? l : 0); |
691 | 668 | ||
692 | /* write uncompressed block size */ | 669 | /* write uncompressed block size */ |
693 | write32(src_len); | ||
694 | |||
695 | /* exit if last block */ | 670 | /* exit if last block */ |
696 | if (src_len == 0) | 671 | if (src_len == 0) { |
672 | write32(0); | ||
697 | break; | 673 | break; |
674 | } | ||
675 | *wordptr++ = htonl(src_len); | ||
698 | 676 | ||
699 | /* compute checksum of uncompressed block */ | 677 | /* compute checksum of uncompressed block */ |
700 | if (h->flags & F_ADLER32_D) | 678 | if (h->flags32 & F_ADLER32_D) |
701 | d_adler32 = lzo_adler32(ADLER32_INIT_VALUE, b1, src_len); | 679 | d_adler32 = lzo_adler32(ADLER32_INIT_VALUE, b1, src_len); |
702 | if (h->flags & F_CRC32_D) | 680 | if (h->flags32 & F_CRC32_D) |
703 | d_crc32 = lzo_crc32(CRC32_INIT_VALUE, b1, src_len); | 681 | d_crc32 = lzo_crc32(CRC32_INIT_VALUE, b1, src_len); |
704 | 682 | ||
705 | /* compress */ | 683 | /* compress */ |
706 | if (h->method == M_LZO1X_1) | 684 | if (h->method == M_LZO1X_1) |
707 | r = lzo1x_1_compress(b1, src_len, b2, &dst_len, wrk_mem); | 685 | r = lzo1x_1_compress(b1, src_len, b2, &dst_len, wrk_mem); |
708 | else if (h->method == M_LZO1X_1_15) | 686 | else IF_LZOP_COMPR_HIGH(if (h->method == M_LZO1X_1_15)) |
709 | r = lzo1x_1_15_compress(b1, src_len, b2, &dst_len, wrk_mem); | 687 | r = lzo1x_1_15_compress(b1, src_len, b2, &dst_len, wrk_mem); |
710 | #if ENABLE_LZOP_COMPR_HIGH | 688 | #if ENABLE_LZOP_COMPR_HIGH |
711 | else if (h->method == M_LZO1X_999) | 689 | else /* must be h->method == M_LZO1X_999 */ |
712 | r = lzo1x_999_compress_level(b1, src_len, b2, &dst_len, | 690 | r = lzo1x_999_compress_level(b1, src_len, b2, &dst_len, |
713 | wrk_mem, h->level); | 691 | wrk_mem, h->level); |
714 | #endif | 692 | #endif |
715 | else | ||
716 | bb_error_msg_and_die("internal error"); | ||
717 | |||
718 | if (r != 0) /* not LZO_E_OK */ | 693 | if (r != 0) /* not LZO_E_OK */ |
719 | bb_error_msg_and_die("internal error - compression failed"); | 694 | bb_error_msg_and_die("%s: %s", "internal error", "compression"); |
720 | 695 | ||
721 | /* write compressed block size */ | 696 | /* write compressed block size */ |
722 | if (dst_len < src_len) { | 697 | if (dst_len < src_len) { |
@@ -725,32 +700,38 @@ static NOINLINE int lzo_compress(const header_t *h) | |||
725 | unsigned new_len = src_len; | 700 | unsigned new_len = src_len; |
726 | r = lzo1x_optimize(b2, dst_len, b1, &new_len /*, NULL*/); | 701 | r = lzo1x_optimize(b2, dst_len, b1, &new_len /*, NULL*/); |
727 | if (r != 0 /*LZO_E_OK*/ || new_len != src_len) | 702 | if (r != 0 /*LZO_E_OK*/ || new_len != src_len) |
728 | bb_error_msg_and_die("internal error - optimization failed"); | 703 | bb_error_msg_and_die("%s: %s", "internal error", "optimization"); |
729 | } | 704 | } |
730 | write32(dst_len); | 705 | *wordptr++ = htonl(dst_len); |
731 | } else { | 706 | } else { |
732 | /* data actually expanded => store data uncompressed */ | 707 | /* data actually expanded => store data uncompressed */ |
733 | write32(src_len); | 708 | *wordptr++ = htonl(src_len); |
734 | } | 709 | } |
735 | 710 | ||
736 | /* write checksum of uncompressed block */ | 711 | /* write checksum of uncompressed block */ |
737 | if (h->flags & F_ADLER32_D) | 712 | if (h->flags32 & F_ADLER32_D) |
738 | write32(d_adler32); | 713 | *wordptr++ = htonl(d_adler32); |
739 | if (h->flags & F_CRC32_D) | 714 | if (h->flags32 & F_CRC32_D) |
740 | write32(d_crc32); | 715 | *wordptr++ = htonl(d_crc32); |
741 | 716 | ||
742 | if (dst_len < src_len) { | 717 | if (dst_len < src_len) { |
743 | /* write checksum of compressed block */ | 718 | /* write checksum of compressed block */ |
744 | if (h->flags & F_ADLER32_C) | 719 | if (h->flags32 & F_ADLER32_C) |
745 | write32(lzo_adler32(ADLER32_INIT_VALUE, b2, dst_len)); | 720 | *wordptr++ = htonl(lzo_adler32(ADLER32_INIT_VALUE, b2, dst_len)); |
746 | if (h->flags & F_CRC32_C) | 721 | if (h->flags32 & F_CRC32_C) |
747 | write32(lzo_crc32(CRC32_INIT_VALUE, b2, dst_len)); | 722 | *wordptr++ = htonl(lzo_crc32(CRC32_INIT_VALUE, b2, dst_len)); |
723 | } | ||
724 | xwrite(1, wordbuf, ((char*)wordptr) - ((char*)wordbuf)); | ||
725 | if (dst_len < src_len) { | ||
748 | /* write compressed block data */ | 726 | /* write compressed block data */ |
749 | xwrite(1, b2, dst_len); | 727 | xwrite(1, b2, dst_len); |
750 | } else { | 728 | } else { |
751 | /* write uncompressed block data */ | 729 | /* write uncompressed block data */ |
752 | xwrite(1, b1, src_len); | 730 | xwrite(1, b1, src_len); |
753 | } | 731 | } |
732 | // /* if full_read() was nevertheless "short", it was EOF */ | ||
733 | // if (src_len < block_size) | ||
734 | // break; | ||
754 | } | 735 | } |
755 | 736 | ||
756 | free(wrk_mem); | 737 | free(wrk_mem); |
@@ -777,7 +758,9 @@ static FAST_FUNC void lzo_check( | |||
777 | /**********************************************************************/ | 758 | /**********************************************************************/ |
778 | // decompress a file | 759 | // decompress a file |
779 | /**********************************************************************/ | 760 | /**********************************************************************/ |
780 | static NOINLINE int lzo_decompress(const header_t *h) | 761 | // used to have "const header_t *h" parameter, but since it uses |
762 | // only flags32 field, changed to receive only that. | ||
763 | static NOINLINE int lzo_decompress(uint32_t h_flags32) | ||
781 | { | 764 | { |
782 | unsigned block_size = LZO_BLOCK_SIZE; | 765 | unsigned block_size = LZO_BLOCK_SIZE; |
783 | int r; | 766 | int r; |
@@ -822,16 +805,16 @@ static NOINLINE int lzo_decompress(const header_t *h) | |||
822 | } | 805 | } |
823 | 806 | ||
824 | /* read checksum of uncompressed block */ | 807 | /* read checksum of uncompressed block */ |
825 | if (h->flags & F_ADLER32_D) | 808 | if (h_flags32 & F_ADLER32_D) |
826 | d_adler32 = read32(); | 809 | d_adler32 = read32(); |
827 | if (h->flags & F_CRC32_D) | 810 | if (h_flags32 & F_CRC32_D) |
828 | d_crc32 = read32(); | 811 | d_crc32 = read32(); |
829 | 812 | ||
830 | /* read checksum of compressed block */ | 813 | /* read checksum of compressed block */ |
831 | if (src_len < dst_len) { | 814 | if (src_len < dst_len) { |
832 | if (h->flags & F_ADLER32_C) | 815 | if (h_flags32 & F_ADLER32_C) |
833 | c_adler32 = read32(); | 816 | c_adler32 = read32(); |
834 | if (h->flags & F_CRC32_C) | 817 | if (h_flags32 & F_CRC32_C) |
835 | c_crc32 = read32(); | 818 | c_crc32 = read32(); |
836 | } | 819 | } |
837 | 820 | ||
@@ -846,11 +829,11 @@ static NOINLINE int lzo_decompress(const header_t *h) | |||
846 | 829 | ||
847 | if (!(option_mask32 & OPT_F)) { | 830 | if (!(option_mask32 & OPT_F)) { |
848 | /* verify checksum of compressed block */ | 831 | /* verify checksum of compressed block */ |
849 | if (h->flags & F_ADLER32_C) | 832 | if (h_flags32 & F_ADLER32_C) |
850 | lzo_check(ADLER32_INIT_VALUE, | 833 | lzo_check(ADLER32_INIT_VALUE, |
851 | b1, src_len, | 834 | b1, src_len, |
852 | lzo_adler32, c_adler32); | 835 | lzo_adler32, c_adler32); |
853 | if (h->flags & F_CRC32_C) | 836 | if (h_flags32 & F_CRC32_C) |
854 | lzo_check(CRC32_INIT_VALUE, | 837 | lzo_check(CRC32_INIT_VALUE, |
855 | b1, src_len, | 838 | b1, src_len, |
856 | lzo_crc32, c_crc32); | 839 | lzo_crc32, c_crc32); |
@@ -873,11 +856,11 @@ static NOINLINE int lzo_decompress(const header_t *h) | |||
873 | 856 | ||
874 | if (!(option_mask32 & OPT_F)) { | 857 | if (!(option_mask32 & OPT_F)) { |
875 | /* verify checksum of uncompressed block */ | 858 | /* verify checksum of uncompressed block */ |
876 | if (h->flags & F_ADLER32_D) | 859 | if (h_flags32 & F_ADLER32_D) |
877 | lzo_check(ADLER32_INIT_VALUE, | 860 | lzo_check(ADLER32_INIT_VALUE, |
878 | dst, dst_len, | 861 | dst, dst_len, |
879 | lzo_adler32, d_adler32); | 862 | lzo_adler32, d_adler32); |
880 | if (h->flags & F_CRC32_D) | 863 | if (h_flags32 & F_CRC32_D) |
881 | lzo_check(CRC32_INIT_VALUE, | 864 | lzo_check(CRC32_INIT_VALUE, |
882 | dst, dst_len, | 865 | dst, dst_len, |
883 | lzo_crc32, d_crc32); | 866 | lzo_crc32, d_crc32); |
@@ -917,7 +900,7 @@ static NOINLINE int lzo_decompress(const header_t *h) | |||
917 | * -00000020 00 00 2d 67 04 17 00 04 00 00 00 03 ed ec 9d 6d | 900 | * -00000020 00 00 2d 67 04 17 00 04 00 00 00 03 ed ec 9d 6d |
918 | * +00000020 00 00 10 5f 00 c1 00 04 00 00 00 03 ed ec 9d 6d | 901 | * +00000020 00 00 10 5f 00 c1 00 04 00 00 00 03 ed ec 9d 6d |
919 | * ^^^^^^^^^^^ | 902 | * ^^^^^^^^^^^ |
920 | * chksum_out | 903 | * chksum |
921 | * The rest is identical. | 904 | * The rest is identical. |
922 | */ | 905 | */ |
923 | static const unsigned char lzop_magic[9] ALIGN1 = { | 906 | static const unsigned char lzop_magic[9] ALIGN1 = { |
@@ -936,138 +919,138 @@ static void check_magic(void) | |||
936 | /**********************************************************************/ | 919 | /**********************************************************************/ |
937 | // lzop file header | 920 | // lzop file header |
938 | /**********************************************************************/ | 921 | /**********************************************************************/ |
939 | static void write_header(const header_t *h) | 922 | static void write_header(header_t *h) |
940 | { | 923 | { |
941 | int l; | 924 | char *end; |
942 | 925 | ||
943 | xwrite(1, lzop_magic, sizeof(lzop_magic)); | 926 | xwrite(1, lzop_magic, sizeof(lzop_magic)); |
944 | 927 | ||
945 | init_chksum(&G.chksum_out); | 928 | init_chksum(); |
946 | 929 | ||
947 | f_write16(h->version); | 930 | /* Our caller leaves name zero-filled, so len == 0 */ |
948 | f_write16(h->lib_version); | 931 | end = h->len_and_name+1 + 0; /* 0 is strlen(h->len_and_name+1) */ |
949 | f_write16(h->version_needed_to_extract); | 932 | /* Store length byte */ |
950 | f_write8(h->method); | 933 | /*h->len_and_name[0] = end - (h->len_and_name+1); - zero already */ |
951 | f_write8(h->level); | ||
952 | f_write32(h->flags); | ||
953 | f_write32(h->mode); | ||
954 | f_write32(h->mtime); | ||
955 | f_write32(h->gmtdiff); | ||
956 | 934 | ||
957 | l = (int) strlen(h->name); | 935 | f_write(&h->version_be16, end - (char*)&h->version_be16); |
958 | f_write8(l); | ||
959 | if (l) | ||
960 | f_write(h->name, l); | ||
961 | 936 | ||
962 | f_write32(chksum_getresult(&G.chksum_out, h)); | 937 | h->flags32 = htonl(h->flags32); /* native endianness for lzo_compress() */ |
938 | |||
939 | write32(chksum_getresult(h->flags32)); | ||
963 | } | 940 | } |
964 | 941 | ||
965 | static int read_header(header_t *h) | 942 | static int read_header(header_t *h) |
966 | { | 943 | { |
967 | int r; | ||
968 | int l; | 944 | int l; |
969 | uint32_t checksum; | 945 | uint32_t checksum; |
946 | /* As it stands now, only h->flags32 is used by our caller. | ||
947 | * Therefore we don't store many fields in h->FIELD. | ||
948 | */ | ||
949 | unsigned h_version; | ||
950 | unsigned h_version_needed_to_extract; | ||
970 | 951 | ||
971 | memset(h, 0, sizeof(*h)); | 952 | init_chksum(); |
972 | h->version_needed_to_extract = 0x0900; /* first lzop version */ | ||
973 | h->level = 0; | ||
974 | |||
975 | init_chksum(&G.chksum_in); | ||
976 | 953 | ||
977 | h->version = f_read16(); | 954 | /* We don't support versions < 0.94, since 0.94 |
978 | if (h->version < 0x0900) | 955 | * came only 2 months after 0.90: |
979 | return 3; | 956 | * 0.90 (10 Aug 1997): First public release of lzop |
980 | h->lib_version = f_read16(); | 957 | * 0.94 (15 Oct 1997): Header format change |
981 | if (h->version >= 0x0940) { | 958 | */ |
982 | h->version_needed_to_extract = f_read16(); | ||
983 | if (h->version_needed_to_extract > LZOP_VERSION) | ||
984 | return 16; | ||
985 | if (h->version_needed_to_extract < 0x0900) | ||
986 | return 3; | ||
987 | } | ||
988 | h->method = f_read8(); | ||
989 | if (h->version >= 0x0940) | ||
990 | h->level = f_read8(); | ||
991 | h->flags = f_read32(); | ||
992 | if (h->flags & F_H_FILTER) | ||
993 | return 16; /* filter not supported */ | ||
994 | h->mode = f_read32(); | ||
995 | h->mtime = f_read32(); | ||
996 | if (h->version >= 0x0940) | ||
997 | h->gmtdiff = f_read32(); | ||
998 | 959 | ||
999 | l = f_read8(); | 960 | /* Read up to and including name length byte */ |
1000 | if (l > 0) | 961 | f_read(&h->version_be16, ((char*)&h->len_and_name[1]) - ((char*)&h->version_be16)); |
1001 | f_read(h->name, l); | ||
1002 | h->name[l] = 0; | ||
1003 | 962 | ||
1004 | checksum = chksum_getresult(&G.chksum_in, h); | 963 | h_version = htons(h->version_be16); |
1005 | h->header_checksum = f_read32(); | 964 | if (h_version < 0x0940) |
1006 | if (h->header_checksum != checksum) | 965 | return 3; |
1007 | return 2; | 966 | h_version_needed_to_extract = htons(h->version_needed_to_extract_be16); |
967 | if (h_version_needed_to_extract > LZOP_VERSION) | ||
968 | return 16; | ||
969 | if (h_version_needed_to_extract < 0x0940) | ||
970 | return 3; | ||
1008 | 971 | ||
1009 | if (h->method <= 0) | 972 | if (h->method <= 0) |
1010 | return 14; | 973 | return 14; |
1011 | r = lzo_get_method(h); | ||
1012 | if (r != 0) | ||
1013 | return r; | ||
1014 | 974 | ||
975 | /* former lzo_get_method(h): */ | ||
976 | if (h->method == M_LZO1X_1) { | ||
977 | if (h->level == 0) | ||
978 | h->level = 3; | ||
979 | } else if (h->method == M_LZO1X_1_15) { | ||
980 | if (h->level == 0) | ||
981 | h->level = 1; | ||
982 | } else if (h->method == M_LZO1X_999) { | ||
983 | if (h->level == 0) | ||
984 | h->level = 9; | ||
985 | } else | ||
986 | return -1; /* not a LZO method */ | ||
987 | /* check compression level */ | ||
988 | if (h->level < 1 || h->level > 9) | ||
989 | return 15; | ||
990 | |||
991 | h->flags32 = ntohl(h->flags32); | ||
992 | if (h->flags32 & F_H_FILTER) | ||
993 | return 16; /* filter not supported */ | ||
1015 | /* check reserved flags */ | 994 | /* check reserved flags */ |
1016 | if (h->flags & F_RESERVED) | 995 | if (h->flags32 & F_RESERVED) |
1017 | return -13; | 996 | return -13; |
1018 | 997 | ||
998 | l = h->len_and_name[0]; | ||
999 | if (l > 0) | ||
1000 | /* UNUSED */ f_read(h->len_and_name+1, l); | ||
1001 | /* UNUSED h->len_and_name[1+l] = 0; */ | ||
1002 | |||
1003 | checksum = chksum_getresult(h->flags32); | ||
1004 | if (read32() != checksum) | ||
1005 | return 2; | ||
1006 | |||
1019 | /* skip extra field [not used yet] */ | 1007 | /* skip extra field [not used yet] */ |
1020 | if (h->flags & F_H_EXTRA_FIELD) { | 1008 | if (h->flags32 & F_H_EXTRA_FIELD) { |
1009 | uint32_t extra_field_len; | ||
1010 | uint32_t extra_field_checksum; | ||
1021 | uint32_t k; | 1011 | uint32_t k; |
1012 | char dummy; | ||
1022 | 1013 | ||
1023 | /* note: the checksum also covers the length */ | 1014 | /* note: the checksum also covers the length */ |
1024 | init_chksum(&G.chksum_in); | 1015 | init_chksum(); |
1025 | h->extra_field_len = f_read32(); | 1016 | extra_field_len = f_read32(); |
1026 | for (k = 0; k < h->extra_field_len; k++) | 1017 | for (k = 0; k < extra_field_len; k++) |
1027 | f_read8(); | 1018 | f_read(&dummy, 1); |
1028 | checksum = chksum_getresult(&G.chksum_in, h); | 1019 | checksum = chksum_getresult(h->flags32); |
1029 | h->extra_field_checksum = f_read32(); | 1020 | extra_field_checksum = read32(); |
1030 | if (h->extra_field_checksum != checksum) | 1021 | if (extra_field_checksum != checksum) |
1031 | return 3; | 1022 | return 3; |
1032 | } | 1023 | } |
1033 | 1024 | ||
1034 | return 0; | 1025 | return 0; |
1035 | } | 1026 | } |
1036 | 1027 | ||
1037 | static void p_header(header_t *h) | ||
1038 | { | ||
1039 | int r; | ||
1040 | |||
1041 | r = read_header(h); | ||
1042 | if (r == 0) | ||
1043 | return; | ||
1044 | bb_error_msg_and_die("header_error %d", r); | ||
1045 | } | ||
1046 | |||
1047 | /**********************************************************************/ | 1028 | /**********************************************************************/ |
1048 | // compress | 1029 | // compress |
1049 | /**********************************************************************/ | 1030 | /**********************************************************************/ |
1050 | static void lzo_set_method(header_t *h) | 1031 | static void lzo_set_method(header_t *h) |
1051 | { | 1032 | { |
1052 | int level = 1; | 1033 | smallint level; |
1034 | |||
1035 | /* levels 2..6 or none (defaults to level 3) */ | ||
1036 | h->method = M_LZO1X_1; | ||
1037 | level = 5; /* levels 2-6 are actually the same */ | ||
1053 | 1038 | ||
1054 | if (option_mask32 & OPT_1) { | 1039 | if (option_mask32 & OPT_1) { |
1055 | h->method = M_LZO1X_1_15; | 1040 | h->method = M_LZO1X_1_15; |
1056 | } else if (option_mask32 & OPT_789) { | 1041 | level = 1; |
1042 | } | ||
1043 | if (option_mask32 & OPT_789) { | ||
1057 | #if ENABLE_LZOP_COMPR_HIGH | 1044 | #if ENABLE_LZOP_COMPR_HIGH |
1058 | h->method = M_LZO1X_999; | 1045 | h->method = M_LZO1X_999; |
1046 | level = 9; | ||
1059 | if (option_mask32 & OPT_7) | 1047 | if (option_mask32 & OPT_7) |
1060 | level = 7; | 1048 | level = 7; |
1061 | else if (option_mask32 & OPT_8) | 1049 | else if (option_mask32 & OPT_8) |
1062 | level = 8; | 1050 | level = 8; |
1063 | else | ||
1064 | level = 9; | ||
1065 | #else | 1051 | #else |
1066 | bb_error_msg_and_die("high compression not compiled in"); | 1052 | bb_error_msg_and_die("high compression not compiled in"); |
1067 | #endif | 1053 | #endif |
1068 | } else { /* levels 2..6 or none (defaults to level 3) */ | ||
1069 | h->method = M_LZO1X_1; | ||
1070 | level = 5; /* levels 2-6 are actually the same */ | ||
1071 | } | 1054 | } |
1072 | 1055 | ||
1073 | h->level = level; | 1056 | h->level = level; |
@@ -1082,18 +1065,21 @@ static int do_lzo_compress(void) | |||
1082 | 1065 | ||
1083 | lzo_set_method(h); | 1066 | lzo_set_method(h); |
1084 | 1067 | ||
1085 | h->version = (LZOP_VERSION & 0xffff); | 1068 | h->version_be16 = htons(LZOP_VERSION & 0xffff); |
1086 | h->version_needed_to_extract = 0x0940; | 1069 | h->version_needed_to_extract_be16 = htons(0x0940); |
1087 | h->lib_version = lzo_version() & 0xffff; | 1070 | h->lib_version_be16 = htons(lzo_version() & 0xffff); |
1088 | 1071 | ||
1089 | h->flags = (F_OS & F_OS_MASK) | (F_CS & F_CS_MASK); | 1072 | h->flags32 = htonl((F_OS & F_OS_MASK) | (F_CS & F_CS_MASK)); |
1090 | 1073 | ||
1091 | if (!(option_mask32 & OPT_F) || h->method == M_LZO1X_999) { | 1074 | if (!(option_mask32 & OPT_F) || h->method == M_LZO1X_999) { |
1092 | h->flags |= F_ADLER32_D; | 1075 | h->flags32 |= htonl(F_ADLER32_D); |
1093 | if (option_mask32 & OPT_C) | 1076 | if (option_mask32 & OPT_C) |
1094 | h->flags |= F_ADLER32_C; | 1077 | h->flags32 |= htonl(F_ADLER32_C); |
1095 | } | 1078 | } |
1079 | |||
1080 | /* write_header() also converts h->flags32 to native endianness */ | ||
1096 | write_header(h); | 1081 | write_header(h); |
1082 | |||
1097 | return lzo_compress(h); | 1083 | return lzo_compress(h); |
1098 | #undef h | 1084 | #undef h |
1099 | } | 1085 | } |
@@ -1103,11 +1089,14 @@ static int do_lzo_compress(void) | |||
1103 | /**********************************************************************/ | 1089 | /**********************************************************************/ |
1104 | static int do_lzo_decompress(void) | 1090 | static int do_lzo_decompress(void) |
1105 | { | 1091 | { |
1092 | int r; | ||
1106 | header_t header; | 1093 | header_t header; |
1107 | 1094 | ||
1108 | check_magic(); | 1095 | check_magic(); |
1109 | p_header(&header); | 1096 | r = read_header(&header); |
1110 | return lzo_decompress(&header); | 1097 | if (r != 0) |
1098 | bb_error_msg_and_die("header_error %d", r); | ||
1099 | return lzo_decompress(header.flags32); | ||
1111 | } | 1100 | } |
1112 | 1101 | ||
1113 | static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_ext UNUSED_PARAM) | 1102 | static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_ext UNUSED_PARAM) |
@@ -1132,6 +1121,8 @@ static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_state_t *xstate | |||
1132 | int lzop_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1121 | int lzop_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1133 | int lzop_main(int argc UNUSED_PARAM, char **argv) | 1122 | int lzop_main(int argc UNUSED_PARAM, char **argv) |
1134 | { | 1123 | { |
1124 | INIT_G(); | ||
1125 | |||
1135 | getopt32(argv, OPTION_STRING); | 1126 | getopt32(argv, OPTION_STRING); |
1136 | argv += optind; | 1127 | argv += optind; |
1137 | /* -U is "anti -k", invert bit for bbunpack(): */ | 1128 | /* -U is "anti -k", invert bit for bbunpack(): */ |
diff --git a/archival/tar.c b/archival/tar.c index 308ce7701..afd8cfec5 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -799,8 +799,8 @@ static llist_t *append_file_list_to_list(llist_t *list) | |||
799 | //usage:#define tar_full_usage "\n\n" | 799 | //usage:#define tar_full_usage "\n\n" |
800 | //usage: IF_FEATURE_TAR_CREATE("Create, extract, ") | 800 | //usage: IF_FEATURE_TAR_CREATE("Create, extract, ") |
801 | //usage: IF_NOT_FEATURE_TAR_CREATE("Extract ") | 801 | //usage: IF_NOT_FEATURE_TAR_CREATE("Extract ") |
802 | //usage: "or list files from a tar file\n" | 802 | //usage: "or list files from a tar file" |
803 | //usage: "\nOperation:" | 803 | //usage: "\n" |
804 | //usage: IF_FEATURE_TAR_CREATE( | 804 | //usage: IF_FEATURE_TAR_CREATE( |
805 | //usage: "\n c Create" | 805 | //usage: "\n c Create" |
806 | //usage: ) | 806 | //usage: ) |