aboutsummaryrefslogtreecommitdiff
path: root/deflate.c
diff options
context:
space:
mode:
authorMark Adler <git@madler.net>2026-01-04 10:34:44 -0600
committerMark Adler <git@madler.net>2026-01-05 15:03:04 -0600
commit916dc1ac351795c9bf86a3d19c3667b014b9d28e (patch)
tree08efd9aa0c5387fe80c1ce15a9fdb0ca8e29c01c /deflate.c
parentfd366384cf324d750596feb03be44ddf4d1e6acd (diff)
downloadzlib-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.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/deflate.c b/deflate.c
index cd852669..6f886306 100644
--- a/deflate.c
+++ b/deflate.c
@@ -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 */
842uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { 842z_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}
915uLong 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/* =========================================================================