diff options
Diffstat (limited to 'bzlib.c')
-rw-r--r-- | bzlib.c | 59 |
1 files changed, 41 insertions, 18 deletions
@@ -8,7 +8,7 @@ | |||
8 | This file is a part of bzip2 and/or libbzip2, a program and | 8 | This file is a part of bzip2 and/or libbzip2, a program and |
9 | library for lossless, block-sorting data compression. | 9 | library for lossless, block-sorting data compression. |
10 | 10 | ||
11 | Copyright (C) 1996-2002 Julian R Seward. All rights reserved. | 11 | Copyright (C) 1996-2005 Julian R Seward. All rights reserved. |
12 | 12 | ||
13 | Redistribution and use in source and binary forms, with or without | 13 | Redistribution and use in source and binary forms, with or without |
14 | modification, are permitted provided that the following conditions | 14 | modification, are permitted provided that the following conditions |
@@ -42,7 +42,7 @@ | |||
42 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 42 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
43 | 43 | ||
44 | Julian Seward, Cambridge, UK. | 44 | Julian Seward, Cambridge, UK. |
45 | jseward@acm.org | 45 | jseward@bzip.org |
46 | bzip2/libbzip2 version 1.0 of 21 March 2000 | 46 | bzip2/libbzip2 version 1.0 of 21 March 2000 |
47 | 47 | ||
48 | This program is based on (at least) the work of: | 48 | This program is based on (at least) the work of: |
@@ -88,12 +88,12 @@ void BZ2_bz__AssertH__fail ( int errcode ) | |||
88 | fprintf(stderr, | 88 | fprintf(stderr, |
89 | "\n\nbzip2/libbzip2: internal error number %d.\n" | 89 | "\n\nbzip2/libbzip2: internal error number %d.\n" |
90 | "This is a bug in bzip2/libbzip2, %s.\n" | 90 | "This is a bug in bzip2/libbzip2, %s.\n" |
91 | "Please report it to me at: jseward@acm.org. If this happened\n" | 91 | "Please report it to me at: jseward@bzip.org. If this happened\n" |
92 | "when you were using some program which uses libbzip2 as a\n" | 92 | "when you were using some program which uses libbzip2 as a\n" |
93 | "component, you should also report this bug to the author(s)\n" | 93 | "component, you should also report this bug to the author(s)\n" |
94 | "of that program. Please make an effort to report this bug;\n" | 94 | "of that program. Please make an effort to report this bug;\n" |
95 | "timely and accurate bug reports eventually lead to higher\n" | 95 | "timely and accurate bug reports eventually lead to higher\n" |
96 | "quality software. Thanks. Julian Seward, 30 December 2001.\n\n", | 96 | "quality software. Thanks. Julian Seward, 15 February 2005.\n\n", |
97 | errcode, | 97 | errcode, |
98 | BZ2_bzlibVersion() | 98 | BZ2_bzlibVersion() |
99 | ); | 99 | ); |
@@ -574,8 +574,11 @@ int BZ_API(BZ2_bzDecompressInit) | |||
574 | 574 | ||
575 | 575 | ||
576 | /*---------------------------------------------------*/ | 576 | /*---------------------------------------------------*/ |
577 | /* Return True iff data corruption is discovered. | ||
578 | Returns False if there is no problem. | ||
579 | */ | ||
577 | static | 580 | static |
578 | void unRLE_obuf_to_output_FAST ( DState* s ) | 581 | Bool unRLE_obuf_to_output_FAST ( DState* s ) |
579 | { | 582 | { |
580 | UChar k1; | 583 | UChar k1; |
581 | 584 | ||
@@ -584,7 +587,7 @@ void unRLE_obuf_to_output_FAST ( DState* s ) | |||
584 | while (True) { | 587 | while (True) { |
585 | /* try to finish existing run */ | 588 | /* try to finish existing run */ |
586 | while (True) { | 589 | while (True) { |
587 | if (s->strm->avail_out == 0) return; | 590 | if (s->strm->avail_out == 0) return False; |
588 | if (s->state_out_len == 0) break; | 591 | if (s->state_out_len == 0) break; |
589 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; | 592 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; |
590 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); | 593 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); |
@@ -594,10 +597,13 @@ void unRLE_obuf_to_output_FAST ( DState* s ) | |||
594 | s->strm->total_out_lo32++; | 597 | s->strm->total_out_lo32++; |
595 | if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; | 598 | if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; |
596 | } | 599 | } |
597 | 600 | ||
598 | /* can a new run be started? */ | 601 | /* can a new run be started? */ |
599 | if (s->nblock_used == s->save_nblock+1) return; | 602 | if (s->nblock_used == s->save_nblock+1) return False; |
600 | 603 | ||
604 | /* Only caused by corrupt data stream? */ | ||
605 | if (s->nblock_used > s->save_nblock+1) | ||
606 | return True; | ||
601 | 607 | ||
602 | s->state_out_len = 1; | 608 | s->state_out_len = 1; |
603 | s->state_out_ch = s->k0; | 609 | s->state_out_ch = s->k0; |
@@ -667,6 +673,10 @@ void unRLE_obuf_to_output_FAST ( DState* s ) | |||
667 | cs_avail_out--; | 673 | cs_avail_out--; |
668 | } | 674 | } |
669 | } | 675 | } |
676 | /* Only caused by corrupt data stream? */ | ||
677 | if (c_nblock_used > s_save_nblockPP) | ||
678 | return True; | ||
679 | |||
670 | /* can a new run be started? */ | 680 | /* can a new run be started? */ |
671 | if (c_nblock_used == s_save_nblockPP) { | 681 | if (c_nblock_used == s_save_nblockPP) { |
672 | c_state_out_len = 0; goto return_notr; | 682 | c_state_out_len = 0; goto return_notr; |
@@ -712,6 +722,7 @@ void unRLE_obuf_to_output_FAST ( DState* s ) | |||
712 | s->strm->avail_out = cs_avail_out; | 722 | s->strm->avail_out = cs_avail_out; |
713 | /* end save */ | 723 | /* end save */ |
714 | } | 724 | } |
725 | return False; | ||
715 | } | 726 | } |
716 | 727 | ||
717 | 728 | ||
@@ -732,8 +743,11 @@ __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) | |||
732 | 743 | ||
733 | 744 | ||
734 | /*---------------------------------------------------*/ | 745 | /*---------------------------------------------------*/ |
746 | /* Return True iff data corruption is discovered. | ||
747 | Returns False if there is no problem. | ||
748 | */ | ||
735 | static | 749 | static |
736 | void unRLE_obuf_to_output_SMALL ( DState* s ) | 750 | Bool unRLE_obuf_to_output_SMALL ( DState* s ) |
737 | { | 751 | { |
738 | UChar k1; | 752 | UChar k1; |
739 | 753 | ||
@@ -742,7 +756,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s ) | |||
742 | while (True) { | 756 | while (True) { |
743 | /* try to finish existing run */ | 757 | /* try to finish existing run */ |
744 | while (True) { | 758 | while (True) { |
745 | if (s->strm->avail_out == 0) return; | 759 | if (s->strm->avail_out == 0) return False; |
746 | if (s->state_out_len == 0) break; | 760 | if (s->state_out_len == 0) break; |
747 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; | 761 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; |
748 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); | 762 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); |
@@ -754,8 +768,11 @@ void unRLE_obuf_to_output_SMALL ( DState* s ) | |||
754 | } | 768 | } |
755 | 769 | ||
756 | /* can a new run be started? */ | 770 | /* can a new run be started? */ |
757 | if (s->nblock_used == s->save_nblock+1) return; | 771 | if (s->nblock_used == s->save_nblock+1) return False; |
758 | 772 | ||
773 | /* Only caused by corrupt data stream? */ | ||
774 | if (s->nblock_used > s->save_nblock+1) | ||
775 | return True; | ||
759 | 776 | ||
760 | s->state_out_len = 1; | 777 | s->state_out_len = 1; |
761 | s->state_out_ch = s->k0; | 778 | s->state_out_ch = s->k0; |
@@ -788,7 +805,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s ) | |||
788 | while (True) { | 805 | while (True) { |
789 | /* try to finish existing run */ | 806 | /* try to finish existing run */ |
790 | while (True) { | 807 | while (True) { |
791 | if (s->strm->avail_out == 0) return; | 808 | if (s->strm->avail_out == 0) return False; |
792 | if (s->state_out_len == 0) break; | 809 | if (s->state_out_len == 0) break; |
793 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; | 810 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; |
794 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); | 811 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); |
@@ -800,7 +817,11 @@ void unRLE_obuf_to_output_SMALL ( DState* s ) | |||
800 | } | 817 | } |
801 | 818 | ||
802 | /* can a new run be started? */ | 819 | /* can a new run be started? */ |
803 | if (s->nblock_used == s->save_nblock+1) return; | 820 | if (s->nblock_used == s->save_nblock+1) return False; |
821 | |||
822 | /* Only caused by corrupt data stream? */ | ||
823 | if (s->nblock_used > s->save_nblock+1) | ||
824 | return True; | ||
804 | 825 | ||
805 | s->state_out_len = 1; | 826 | s->state_out_len = 1; |
806 | s->state_out_ch = s->k0; | 827 | s->state_out_ch = s->k0; |
@@ -830,6 +851,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s ) | |||
830 | /*---------------------------------------------------*/ | 851 | /*---------------------------------------------------*/ |
831 | int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) | 852 | int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) |
832 | { | 853 | { |
854 | Bool corrupt; | ||
833 | DState* s; | 855 | DState* s; |
834 | if (strm == NULL) return BZ_PARAM_ERROR; | 856 | if (strm == NULL) return BZ_PARAM_ERROR; |
835 | s = strm->state; | 857 | s = strm->state; |
@@ -840,12 +862,13 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) | |||
840 | if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; | 862 | if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; |
841 | if (s->state == BZ_X_OUTPUT) { | 863 | if (s->state == BZ_X_OUTPUT) { |
842 | if (s->smallDecompress) | 864 | if (s->smallDecompress) |
843 | unRLE_obuf_to_output_SMALL ( s ); else | 865 | corrupt = unRLE_obuf_to_output_SMALL ( s ); else |
844 | unRLE_obuf_to_output_FAST ( s ); | 866 | corrupt = unRLE_obuf_to_output_FAST ( s ); |
867 | if (corrupt) return BZ_DATA_ERROR; | ||
845 | if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) { | 868 | if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) { |
846 | BZ_FINALISE_CRC ( s->calculatedBlockCRC ); | 869 | BZ_FINALISE_CRC ( s->calculatedBlockCRC ); |
847 | if (s->verbosity >= 3) | 870 | if (s->verbosity >= 3) |
848 | VPrintf2 ( " {0x%x, 0x%x}", s->storedBlockCRC, | 871 | VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, |
849 | s->calculatedBlockCRC ); | 872 | s->calculatedBlockCRC ); |
850 | if (s->verbosity >= 2) VPrintf0 ( "]" ); | 873 | if (s->verbosity >= 2) VPrintf0 ( "]" ); |
851 | if (s->calculatedBlockCRC != s->storedBlockCRC) | 874 | if (s->calculatedBlockCRC != s->storedBlockCRC) |
@@ -863,7 +886,7 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) | |||
863 | Int32 r = BZ2_decompress ( s ); | 886 | Int32 r = BZ2_decompress ( s ); |
864 | if (r == BZ_STREAM_END) { | 887 | if (r == BZ_STREAM_END) { |
865 | if (s->verbosity >= 3) | 888 | if (s->verbosity >= 3) |
866 | VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x", | 889 | VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x", |
867 | s->storedCombinedCRC, s->calculatedCombinedCRC ); | 890 | s->storedCombinedCRC, s->calculatedCombinedCRC ); |
868 | if (s->calculatedCombinedCRC != s->storedCombinedCRC) | 891 | if (s->calculatedCombinedCRC != s->storedCombinedCRC) |
869 | return BZ_DATA_ERROR; | 892 | return BZ_DATA_ERROR; |