diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-08 13:32:47 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-08 13:33:43 +0200 |
commit | 434f95960ad484d09ce0cad5dbf44b11312963f8 (patch) | |
tree | 909f3ed1aa8c9e9fc94748e1affa64cf48852479 /archival/lzop.c | |
parent | 7924b69f99223b0fdf5538ed335f42a81be838d0 (diff) | |
download | busybox-w32-434f95960ad484d09ce0cad5dbf44b11312963f8.tar.gz busybox-w32-434f95960ad484d09ce0cad5dbf44b11312963f8.tar.bz2 busybox-w32-434f95960ad484d09ce0cad5dbf44b11312963f8.zip |
lzop: code shrink by using header_t matching on-disk layout
function old new delta
add_bytes_to_chksum 37 47 +10
lzo_decompress 524 532 +8
init_chksum 14 21 +7
chksum_getresult 13 17 +4
f_read 33 28 -5
f_write8 20 - -20
f_write32 22 - -22
f_write16 25 - -25
f_write 36 - -36
do_lzo_compress 328 232 -96
do_lzo_decompress 526 411 -115
------------------------------------------------------------------------------
(add/remove: 0/4 grow/shrink: 4/3 up/down: 29/-319) Total: -290 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r-- | archival/lzop.c | 331 |
1 files changed, 154 insertions, 177 deletions
diff --git a/archival/lzop.c b/archival/lzop.c index fef8cdba3..419e1e21f 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 them 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 | |||
597 | static int f_read8(void) | 580 | static int f_read8(void) |
598 | { | 581 | { |
599 | uint8_t v; | 582 | uint8_t v; |
600 | f_read(&v, 1); | 583 | f_read(&v, 1); |
601 | return v; | 584 | return v; |
602 | } | 585 | } |
603 | |||
604 | static void f_write8(uint8_t v) | ||
605 | { | ||
606 | f_write(&v, 1); | ||
607 | } | ||
608 | |||
609 | static unsigned f_read16(void) | 586 | static unsigned f_read16(void) |
610 | { | 587 | { |
611 | uint16_t v; | 588 | uint16_t v; |
612 | f_read(&v, 2); | 589 | f_read(&v, 2); |
613 | return ntohs(v); | 590 | return ntohs(v); |
614 | } | 591 | } |
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) |
@@ -697,9 +663,9 @@ static NOINLINE int lzo_compress(const header_t *h) | |||
697 | break; | 663 | break; |
698 | 664 | ||
699 | /* compute checksum of uncompressed block */ | 665 | /* compute checksum of uncompressed block */ |
700 | if (h->flags & F_ADLER32_D) | 666 | if (h->flags32 & F_ADLER32_D) |
701 | d_adler32 = lzo_adler32(ADLER32_INIT_VALUE, b1, src_len); | 667 | d_adler32 = lzo_adler32(ADLER32_INIT_VALUE, b1, src_len); |
702 | if (h->flags & F_CRC32_D) | 668 | if (h->flags32 & F_CRC32_D) |
703 | d_crc32 = lzo_crc32(CRC32_INIT_VALUE, b1, src_len); | 669 | d_crc32 = lzo_crc32(CRC32_INIT_VALUE, b1, src_len); |
704 | 670 | ||
705 | /* compress */ | 671 | /* compress */ |
@@ -734,16 +700,16 @@ static NOINLINE int lzo_compress(const header_t *h) | |||
734 | } | 700 | } |
735 | 701 | ||
736 | /* write checksum of uncompressed block */ | 702 | /* write checksum of uncompressed block */ |
737 | if (h->flags & F_ADLER32_D) | 703 | if (h->flags32 & F_ADLER32_D) |
738 | write32(d_adler32); | 704 | write32(d_adler32); |
739 | if (h->flags & F_CRC32_D) | 705 | if (h->flags32 & F_CRC32_D) |
740 | write32(d_crc32); | 706 | write32(d_crc32); |
741 | 707 | ||
742 | if (dst_len < src_len) { | 708 | if (dst_len < src_len) { |
743 | /* write checksum of compressed block */ | 709 | /* write checksum of compressed block */ |
744 | if (h->flags & F_ADLER32_C) | 710 | if (h->flags32 & F_ADLER32_C) |
745 | write32(lzo_adler32(ADLER32_INIT_VALUE, b2, dst_len)); | 711 | write32(lzo_adler32(ADLER32_INIT_VALUE, b2, dst_len)); |
746 | if (h->flags & F_CRC32_C) | 712 | if (h->flags32 & F_CRC32_C) |
747 | write32(lzo_crc32(CRC32_INIT_VALUE, b2, dst_len)); | 713 | write32(lzo_crc32(CRC32_INIT_VALUE, b2, dst_len)); |
748 | /* write compressed block data */ | 714 | /* write compressed block data */ |
749 | xwrite(1, b2, dst_len); | 715 | xwrite(1, b2, dst_len); |
@@ -777,7 +743,9 @@ static FAST_FUNC void lzo_check( | |||
777 | /**********************************************************************/ | 743 | /**********************************************************************/ |
778 | // decompress a file | 744 | // decompress a file |
779 | /**********************************************************************/ | 745 | /**********************************************************************/ |
780 | static NOINLINE int lzo_decompress(const header_t *h) | 746 | // used to have "const header_t *h" parameter, but since it uses |
747 | // only flags32 field, changed to receive only that. | ||
748 | static NOINLINE int lzo_decompress(uint32_t h_flags32) | ||
781 | { | 749 | { |
782 | unsigned block_size = LZO_BLOCK_SIZE; | 750 | unsigned block_size = LZO_BLOCK_SIZE; |
783 | int r; | 751 | int r; |
@@ -822,16 +790,16 @@ static NOINLINE int lzo_decompress(const header_t *h) | |||
822 | } | 790 | } |
823 | 791 | ||
824 | /* read checksum of uncompressed block */ | 792 | /* read checksum of uncompressed block */ |
825 | if (h->flags & F_ADLER32_D) | 793 | if (h_flags32 & F_ADLER32_D) |
826 | d_adler32 = read32(); | 794 | d_adler32 = read32(); |
827 | if (h->flags & F_CRC32_D) | 795 | if (h_flags32 & F_CRC32_D) |
828 | d_crc32 = read32(); | 796 | d_crc32 = read32(); |
829 | 797 | ||
830 | /* read checksum of compressed block */ | 798 | /* read checksum of compressed block */ |
831 | if (src_len < dst_len) { | 799 | if (src_len < dst_len) { |
832 | if (h->flags & F_ADLER32_C) | 800 | if (h_flags32 & F_ADLER32_C) |
833 | c_adler32 = read32(); | 801 | c_adler32 = read32(); |
834 | if (h->flags & F_CRC32_C) | 802 | if (h_flags32 & F_CRC32_C) |
835 | c_crc32 = read32(); | 803 | c_crc32 = read32(); |
836 | } | 804 | } |
837 | 805 | ||
@@ -846,11 +814,11 @@ static NOINLINE int lzo_decompress(const header_t *h) | |||
846 | 814 | ||
847 | if (!(option_mask32 & OPT_F)) { | 815 | if (!(option_mask32 & OPT_F)) { |
848 | /* verify checksum of compressed block */ | 816 | /* verify checksum of compressed block */ |
849 | if (h->flags & F_ADLER32_C) | 817 | if (h_flags32 & F_ADLER32_C) |
850 | lzo_check(ADLER32_INIT_VALUE, | 818 | lzo_check(ADLER32_INIT_VALUE, |
851 | b1, src_len, | 819 | b1, src_len, |
852 | lzo_adler32, c_adler32); | 820 | lzo_adler32, c_adler32); |
853 | if (h->flags & F_CRC32_C) | 821 | if (h_flags32 & F_CRC32_C) |
854 | lzo_check(CRC32_INIT_VALUE, | 822 | lzo_check(CRC32_INIT_VALUE, |
855 | b1, src_len, | 823 | b1, src_len, |
856 | lzo_crc32, c_crc32); | 824 | lzo_crc32, c_crc32); |
@@ -873,11 +841,11 @@ static NOINLINE int lzo_decompress(const header_t *h) | |||
873 | 841 | ||
874 | if (!(option_mask32 & OPT_F)) { | 842 | if (!(option_mask32 & OPT_F)) { |
875 | /* verify checksum of uncompressed block */ | 843 | /* verify checksum of uncompressed block */ |
876 | if (h->flags & F_ADLER32_D) | 844 | if (h_flags32 & F_ADLER32_D) |
877 | lzo_check(ADLER32_INIT_VALUE, | 845 | lzo_check(ADLER32_INIT_VALUE, |
878 | dst, dst_len, | 846 | dst, dst_len, |
879 | lzo_adler32, d_adler32); | 847 | lzo_adler32, d_adler32); |
880 | if (h->flags & F_CRC32_D) | 848 | if (h_flags32 & F_CRC32_D) |
881 | lzo_check(CRC32_INIT_VALUE, | 849 | lzo_check(CRC32_INIT_VALUE, |
882 | dst, dst_len, | 850 | dst, dst_len, |
883 | lzo_crc32, d_crc32); | 851 | lzo_crc32, d_crc32); |
@@ -917,7 +885,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 | 885 | * -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 | 886 | * +00000020 00 00 10 5f 00 c1 00 04 00 00 00 03 ed ec 9d 6d |
919 | * ^^^^^^^^^^^ | 887 | * ^^^^^^^^^^^ |
920 | * chksum_out | 888 | * chksum |
921 | * The rest is identical. | 889 | * The rest is identical. |
922 | */ | 890 | */ |
923 | static const unsigned char lzop_magic[9] ALIGN1 = { | 891 | static const unsigned char lzop_magic[9] ALIGN1 = { |
@@ -936,114 +904,115 @@ static void check_magic(void) | |||
936 | /**********************************************************************/ | 904 | /**********************************************************************/ |
937 | // lzop file header | 905 | // lzop file header |
938 | /**********************************************************************/ | 906 | /**********************************************************************/ |
939 | static void write_header(const header_t *h) | 907 | static void write_header(header_t *h) |
940 | { | 908 | { |
941 | int l; | 909 | char *end; |
942 | 910 | ||
943 | xwrite(1, lzop_magic, sizeof(lzop_magic)); | 911 | xwrite(1, lzop_magic, sizeof(lzop_magic)); |
944 | 912 | ||
945 | init_chksum(&G.chksum_out); | 913 | init_chksum(); |
946 | 914 | ||
947 | f_write16(h->version); | 915 | /* Our caller leaves name zero-filled, so len == 0 */ |
948 | f_write16(h->lib_version); | 916 | end = h->len_and_name+1 + 0; /* 0 is strlen(h->len_and_name+1) */ |
949 | f_write16(h->version_needed_to_extract); | 917 | /* Store length byte */ |
950 | f_write8(h->method); | 918 | /*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 | 919 | ||
957 | l = (int) strlen(h->name); | 920 | f_write(&h->version_be16, end - (char*)&h->version_be16); |
958 | f_write8(l); | ||
959 | if (l) | ||
960 | f_write(h->name, l); | ||
961 | 921 | ||
962 | f_write32(chksum_getresult(&G.chksum_out, h)); | 922 | h->flags32 = htonl(h->flags32); /* native endianness for lzo_compress() */ |
923 | |||
924 | /*f_*/write32(chksum_getresult(h->flags32)); | ||
963 | } | 925 | } |
964 | 926 | ||
965 | static int read_header(header_t *h) | 927 | static int read_header(header_t *h) |
966 | { | 928 | { |
967 | int r; | ||
968 | int l; | 929 | int l; |
969 | uint32_t checksum; | 930 | uint32_t checksum; |
931 | unsigned h_version; | ||
932 | uint8_t h_method, h_level; | ||
970 | 933 | ||
971 | memset(h, 0, sizeof(*h)); | 934 | init_chksum(); |
972 | h->version_needed_to_extract = 0x0900; /* first lzop version */ | ||
973 | h->level = 0; | ||
974 | |||
975 | init_chksum(&G.chksum_in); | ||
976 | 935 | ||
977 | h->version = f_read16(); | 936 | /* As it stands now, only h->flags32 is used by our caller. |
978 | if (h->version < 0x0900) | 937 | * Therefore we don't store many fields in h->field. |
938 | */ | ||
939 | h_version = f_read16(); | ||
940 | if (h_version < 0x0900) | ||
979 | return 3; | 941 | return 3; |
980 | h->lib_version = f_read16(); | 942 | /* UNUSED h->lib_version_be16 = */ f_read16(); |
981 | if (h->version >= 0x0940) { | 943 | if (h_version >= 0x0940) { |
982 | h->version_needed_to_extract = f_read16(); | 944 | unsigned h_version_needed_to_extract = f_read16(); |
983 | if (h->version_needed_to_extract > LZOP_VERSION) | 945 | if (h_version_needed_to_extract > LZOP_VERSION) |
984 | return 16; | 946 | return 16; |
985 | if (h->version_needed_to_extract < 0x0900) | 947 | if (h_version_needed_to_extract < 0x0900) /* first lzop version */ |
986 | return 3; | 948 | return 3; |
987 | } | 949 | } |
988 | h->method = f_read8(); | 950 | |
989 | if (h->version >= 0x0940) | 951 | h_method = f_read8(); |
990 | h->level = f_read8(); | 952 | if (h_method <= 0) |
991 | h->flags = f_read32(); | 953 | return 14; |
992 | if (h->flags & F_H_FILTER) | 954 | h_level = 0; |
955 | if (h_version >= 0x0940) | ||
956 | h_level = f_read8(); | ||
957 | |||
958 | /* former lzo_get_method(h): */ | ||
959 | if (h_method == M_LZO1X_1) { | ||
960 | if (h_level == 0) | ||
961 | h_level = 3; | ||
962 | } else if (h_method == M_LZO1X_1_15) { | ||
963 | if (h_level == 0) | ||
964 | h_level = 1; | ||
965 | } else if (h_method == M_LZO1X_999) { | ||
966 | if (h_level == 0) | ||
967 | h_level = 9; | ||
968 | } else | ||
969 | return -1; /* not a LZO method */ | ||
970 | /* check compression level */ | ||
971 | if (h_level < 1 || h_level > 9) | ||
972 | return 15; | ||
973 | |||
974 | h->flags32 = f_read32(); | ||
975 | if (h->flags32 & F_H_FILTER) | ||
993 | return 16; /* filter not supported */ | 976 | return 16; /* filter not supported */ |
994 | h->mode = f_read32(); | 977 | /* check reserved flags */ |
995 | h->mtime = f_read32(); | 978 | if (h->flags32 & F_RESERVED) |
996 | if (h->version >= 0x0940) | 979 | return -13; |
997 | h->gmtdiff = f_read32(); | 980 | |
981 | /* UNUSED h->mode = */ f_read32(); | ||
982 | /* UNUSED h->mtime = */ f_read32(); | ||
983 | if (h_version >= 0x0940) | ||
984 | /* UNUSED h->gmtdiff = */ f_read32(); | ||
998 | 985 | ||
999 | l = f_read8(); | 986 | l = f_read8(); |
987 | /* UNUSED h->len_and_name[0] = l; */ | ||
988 | /* UNUSED h->len_and_name[1+l] = 0; */ | ||
1000 | if (l > 0) | 989 | if (l > 0) |
1001 | f_read(h->name, l); | 990 | f_read(h->len_and_name+1, l); |
1002 | h->name[l] = 0; | ||
1003 | 991 | ||
1004 | checksum = chksum_getresult(&G.chksum_in, h); | 992 | checksum = chksum_getresult(h->flags32); |
1005 | h->header_checksum = f_read32(); | 993 | if (f_read32() != checksum) |
1006 | if (h->header_checksum != checksum) | ||
1007 | return 2; | 994 | return 2; |
1008 | 995 | ||
1009 | if (h->method <= 0) | ||
1010 | return 14; | ||
1011 | r = lzo_get_method(h); | ||
1012 | if (r != 0) | ||
1013 | return r; | ||
1014 | |||
1015 | /* check reserved flags */ | ||
1016 | if (h->flags & F_RESERVED) | ||
1017 | return -13; | ||
1018 | |||
1019 | /* skip extra field [not used yet] */ | 996 | /* skip extra field [not used yet] */ |
1020 | if (h->flags & F_H_EXTRA_FIELD) { | 997 | if (h->flags32 & F_H_EXTRA_FIELD) { |
998 | uint32_t extra_field_len; | ||
999 | uint32_t extra_field_checksum; | ||
1021 | uint32_t k; | 1000 | uint32_t k; |
1022 | 1001 | ||
1023 | /* note: the checksum also covers the length */ | 1002 | /* note: the checksum also covers the length */ |
1024 | init_chksum(&G.chksum_in); | 1003 | init_chksum(); |
1025 | h->extra_field_len = f_read32(); | 1004 | extra_field_len = f_read32(); |
1026 | for (k = 0; k < h->extra_field_len; k++) | 1005 | for (k = 0; k < extra_field_len; k++) |
1027 | f_read8(); | 1006 | f_read8(); |
1028 | checksum = chksum_getresult(&G.chksum_in, h); | 1007 | checksum = chksum_getresult(h->flags32); |
1029 | h->extra_field_checksum = f_read32(); | 1008 | extra_field_checksum = f_read32(); |
1030 | if (h->extra_field_checksum != checksum) | 1009 | if (extra_field_checksum != checksum) |
1031 | return 3; | 1010 | return 3; |
1032 | } | 1011 | } |
1033 | 1012 | ||
1034 | return 0; | 1013 | return 0; |
1035 | } | 1014 | } |
1036 | 1015 | ||
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 | /**********************************************************************/ | 1016 | /**********************************************************************/ |
1048 | // compress | 1017 | // compress |
1049 | /**********************************************************************/ | 1018 | /**********************************************************************/ |
@@ -1082,18 +1051,21 @@ static int do_lzo_compress(void) | |||
1082 | 1051 | ||
1083 | lzo_set_method(h); | 1052 | lzo_set_method(h); |
1084 | 1053 | ||
1085 | h->version = (LZOP_VERSION & 0xffff); | 1054 | h->version_be16 = htons(LZOP_VERSION & 0xffff); |
1086 | h->version_needed_to_extract = 0x0940; | 1055 | h->version_needed_to_extract_be16 = htons(0x0940); |
1087 | h->lib_version = lzo_version() & 0xffff; | 1056 | h->lib_version_be16 = htons(lzo_version() & 0xffff); |
1088 | 1057 | ||
1089 | h->flags = (F_OS & F_OS_MASK) | (F_CS & F_CS_MASK); | 1058 | h->flags32 = htonl((F_OS & F_OS_MASK) | (F_CS & F_CS_MASK)); |
1090 | 1059 | ||
1091 | if (!(option_mask32 & OPT_F) || h->method == M_LZO1X_999) { | 1060 | if (!(option_mask32 & OPT_F) || h->method == M_LZO1X_999) { |
1092 | h->flags |= F_ADLER32_D; | 1061 | h->flags32 |= htonl(F_ADLER32_D); |
1093 | if (option_mask32 & OPT_C) | 1062 | if (option_mask32 & OPT_C) |
1094 | h->flags |= F_ADLER32_C; | 1063 | h->flags32 |= htonl(F_ADLER32_C); |
1095 | } | 1064 | } |
1065 | |||
1066 | /* write_header() also converts h->flags32 to native endianness */ | ||
1096 | write_header(h); | 1067 | write_header(h); |
1068 | |||
1097 | return lzo_compress(h); | 1069 | return lzo_compress(h); |
1098 | #undef h | 1070 | #undef h |
1099 | } | 1071 | } |
@@ -1103,11 +1075,14 @@ static int do_lzo_compress(void) | |||
1103 | /**********************************************************************/ | 1075 | /**********************************************************************/ |
1104 | static int do_lzo_decompress(void) | 1076 | static int do_lzo_decompress(void) |
1105 | { | 1077 | { |
1078 | int r; | ||
1106 | header_t header; | 1079 | header_t header; |
1107 | 1080 | ||
1108 | check_magic(); | 1081 | check_magic(); |
1109 | p_header(&header); | 1082 | r = read_header(&header); |
1110 | return lzo_decompress(&header); | 1083 | if (r != 0) |
1084 | bb_error_msg_and_die("header_error %d", r); | ||
1085 | return lzo_decompress(header.flags32); | ||
1111 | } | 1086 | } |
1112 | 1087 | ||
1113 | static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_ext UNUSED_PARAM) | 1088 | static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_ext UNUSED_PARAM) |
@@ -1132,6 +1107,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; | 1107 | int lzop_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1133 | int lzop_main(int argc UNUSED_PARAM, char **argv) | 1108 | int lzop_main(int argc UNUSED_PARAM, char **argv) |
1134 | { | 1109 | { |
1110 | INIT_G(); | ||
1111 | |||
1135 | getopt32(argv, OPTION_STRING); | 1112 | getopt32(argv, OPTION_STRING); |
1136 | argv += optind; | 1113 | argv += optind; |
1137 | /* -U is "anti -k", invert bit for bbunpack(): */ | 1114 | /* -U is "anti -k", invert bit for bbunpack(): */ |