diff options
| author | Mark Adler <git@madler.net> | 2026-01-04 10:34:44 -0600 |
|---|---|---|
| committer | Mark Adler <git@madler.net> | 2026-01-05 15:03:04 -0600 |
| commit | 916dc1ac351795c9bf86a3d19c3667b014b9d28e (patch) | |
| tree | 08efd9aa0c5387fe80c1ce15a9fdb0ca8e29c01c /deflate.c | |
| parent | fd366384cf324d750596feb03be44ddf4d1e6acd (diff) | |
| download | zlib-916dc1ac351795c9bf86a3d19c3667b014b9d28e.tar.gz zlib-916dc1ac351795c9bf86a3d19c3667b014b9d28e.tar.bz2 zlib-916dc1ac351795c9bf86a3d19c3667b014b9d28e.zip | |
Add compressBound_z and deflateBound_z functions for large values.
These take and return size_t integers, instead of unsigned longs,
for those platforms with 32-bit longs. This commit also assures
that overflows of either integer type results in the maximum value
for that type, instead of wrapping to small values.
Diffstat (limited to 'deflate.c')
| -rw-r--r-- | deflate.c | 31 |
1 files changed, 22 insertions, 9 deletions
| @@ -839,24 +839,30 @@ int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, | |||
| 839 | * | 839 | * |
| 840 | * Shifts are used to approximate divisions, for speed. | 840 | * Shifts are used to approximate divisions, for speed. |
| 841 | */ | 841 | */ |
| 842 | uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { | 842 | z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen) { |
| 843 | deflate_state *s; | 843 | deflate_state *s; |
| 844 | uLong fixedlen, storelen, wraplen; | 844 | z_size_t fixedlen, storelen, wraplen, bound; |
| 845 | 845 | ||
| 846 | /* upper bound for fixed blocks with 9-bit literals and length 255 | 846 | /* upper bound for fixed blocks with 9-bit literals and length 255 |
| 847 | (memLevel == 2, which is the lowest that may not use stored blocks) -- | 847 | (memLevel == 2, which is the lowest that may not use stored blocks) -- |
| 848 | ~13% overhead plus a small constant */ | 848 | ~13% overhead plus a small constant */ |
| 849 | fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + | 849 | fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + |
| 850 | (sourceLen >> 9) + 4; | 850 | (sourceLen >> 9) + 4; |
| 851 | if (fixedlen < sourceLen) | ||
| 852 | fixedlen = (z_size_t)-1; | ||
| 851 | 853 | ||
| 852 | /* upper bound for stored blocks with length 127 (memLevel == 1) -- | 854 | /* upper bound for stored blocks with length 127 (memLevel == 1) -- |
| 853 | ~4% overhead plus a small constant */ | 855 | ~4% overhead plus a small constant */ |
| 854 | storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + | 856 | storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + |
| 855 | (sourceLen >> 11) + 7; | 857 | (sourceLen >> 11) + 7; |
| 858 | if (storelen < sourceLen) | ||
| 859 | storelen = (z_size_t)-1; | ||
| 856 | 860 | ||
| 857 | /* if can't get parameters, return larger bound plus a wrapper */ | 861 | /* if can't get parameters, return larger bound plus a wrapper */ |
| 858 | if (deflateStateCheck(strm)) | 862 | if (deflateStateCheck(strm)) { |
| 859 | return (fixedlen > storelen ? fixedlen : storelen) + 18; | 863 | bound = fixedlen > storelen ? fixedlen : storelen; |
| 864 | return bound + 18 < bound ? (z_size_t)-1 : bound + 18; | ||
| 865 | } | ||
| 860 | 866 | ||
| 861 | /* compute wrapper length */ | 867 | /* compute wrapper length */ |
| 862 | s = strm->state; | 868 | s = strm->state; |
| @@ -894,14 +900,21 @@ uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { | |||
| 894 | } | 900 | } |
| 895 | 901 | ||
| 896 | /* if not default parameters, return one of the conservative bounds */ | 902 | /* if not default parameters, return one of the conservative bounds */ |
| 897 | if (s->w_bits != 15 || s->hash_bits != 8 + 7) | 903 | if (s->w_bits != 15 || s->hash_bits != 8 + 7) { |
| 898 | return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + | 904 | bound = s->w_bits <= s->hash_bits && s->level ? fixedlen : |
| 899 | wraplen; | 905 | storelen; |
| 906 | return bound + wraplen < bound ? (z_size_t)-1 : bound + wraplen; | ||
| 907 | } | ||
| 900 | 908 | ||
| 901 | /* default settings: return tight bound for that case -- ~0.03% overhead | 909 | /* default settings: return tight bound for that case -- ~0.03% overhead |
| 902 | plus a small constant */ | 910 | plus a small constant */ |
| 903 | return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + | 911 | bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + |
| 904 | (sourceLen >> 25) + 13 - 6 + wraplen; | 912 | (sourceLen >> 25) + 13 - 6 + wraplen; |
| 913 | return bound < sourceLen ? (z_size_t)-1 : bound; | ||
| 914 | } | ||
| 915 | uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { | ||
| 916 | z_size_t bound = deflateBound_z(strm, sourceLen); | ||
| 917 | return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; | ||
| 905 | } | 918 | } |
| 906 | 919 | ||
| 907 | /* ========================================================================= | 920 | /* ========================================================================= |
