Commit 2bed3d6 for zlib
commit 2bed3d61012e102f9ca4006e3a97ea2b7f5d9db6
Author: Mark Adler <git@madler.net>
Date: Sun Oct 25 12:41:54 2026 -0700
Avoid the possibility of overflow in deflate_stored() comparisons.
diff --git a/deflate.c b/deflate.c
index 59220e4..da06c1c 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1677,7 +1677,7 @@ local block_state deflate_stored(deflate_state *s, int flush) {
* possible. If flushing, copy the remaining available input to next_out as
* stored blocks, if there is enough space.
*/
- int last = 0;
+ int last = 0, all;
unsigned len, left, have;
unsigned used = s->strm->avail_in;
do {
@@ -1692,11 +1692,14 @@ local block_state deflate_stored(deflate_state *s, int flush) {
/* maximum stored block length that will fit in avail_out: */
have = s->strm->avail_out - have;
left = (unsigned)(s->strstart - s->block_start); /* window bytes */
- if (len > (ulg)left + s->strm->avail_in)
+ if (left < len && s->strm->avail_in < len - left)
len = left + s->strm->avail_in; /* limit len to the input */
if (len > have)
len = have; /* limit len to the output */
+ /* all is true if len is all of the available input */
+ all = len >= left && len - left == s->strm->avail_in;
+
/* If the stored block would be less than min_block in length, or if
* unable to copy all of the available input when flushing, then try
* copying to the window and the pending buffer instead. Also don't
@@ -1704,13 +1707,13 @@ local block_state deflate_stored(deflate_state *s, int flush) {
*/
if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
flush == Z_NO_FLUSH ||
- len != left + s->strm->avail_in))
+ !all))
break;
/* Make a dummy stored block in pending to get the header bytes,
* including any pending bits. This also updates the debugging counts.
*/
- last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
+ last = flush == Z_FINISH && all ? 1 : 0;
_tr_stored_block(s, (char *)0, 0L, last);
/* Replace the lengths in the dummy stored block with len. */