VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/zlib/deflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/zlib/deflate.c')
-rw-r--r--src/Common/zlib/deflate.c108
1 files changed, 78 insertions, 30 deletions
diff --git a/src/Common/zlib/deflate.c b/src/Common/zlib/deflate.c
index 1ec76144..799fb93c 100644
--- a/src/Common/zlib/deflate.c
+++ b/src/Common/zlib/deflate.c
@@ -1,3 +1,3 @@
/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+ * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
@@ -54,3 +54,3 @@
const char deflate_copyright[] =
- " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
+ " deflate 1.2.12 Copyright 1995-2022 Jean-loup Gailly and Mark Adler ";
/*
@@ -192,4 +192,7 @@ local const config configuration_table[10] = {
#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+ do { \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, \
+ (unsigned)(s->hash_size-1)*sizeof(*s->head)); \
+ } while (0)
@@ -254,7 +257,2 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
if (version == Z_NULL || version[0] != my_version[0] ||
@@ -328,5 +326,43 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+ /* We overlay pending_buf and sym_buf. This works since the average size
+ * for length/distance pairs over any compressed block is assured to be 31
+ * bits or less.
+ *
+ * Analysis: The longest fixed codes are a length code of 8 bits plus 5
+ * extra bits, for lengths 131 to 257. The longest fixed distance codes are
+ * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
+ * possible fixed-codes length/distance pair is then 31 bits total.
+ *
+ * sym_buf starts one-fourth of the way into pending_buf. So there are
+ * three bytes in sym_buf for every four bytes in pending_buf. Each symbol
+ * in sym_buf is three bytes -- two for the distance and one for the
+ * literal/length. As each symbol is consumed, the pointer to the next
+ * sym_buf value to read moves forward three bytes. From that symbol, up to
+ * 31 bits are written to pending_buf. The closest the written pending_buf
+ * bits gets to the next sym_buf symbol to read is just before the last
+ * code is written. At that time, 31*(n-2) bits have been written, just
+ * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
+ * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
+ * symbols are written.) The closest the writing gets to what is unread is
+ * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
+ * can range from 128 to 32768.
+ *
+ * Therefore, at a minimum, there are 142 bits of space between what is
+ * written and what is read in the overlain buffers, so the symbols cannot
+ * be overwritten by the compressed data. That space is actually 139 bits,
+ * due to the three-bit fixed-code block header.
+ *
+ * That covers the case where either Z_FIXED is specified, forcing fixed
+ * codes, or when the use of fixed codes is chosen, because that choice
+ * results in a smaller compressed block than dynamic codes. That latter
+ * condition then assures that the above analysis also covers all dynamic
+ * blocks. A dynamic-code block will only be chosen to be emitted if it has
+ * fewer bits than a fixed-code block would for the same set of symbols.
+ * Therefore its average symbol length is assured to be less than 31. So
+ * the compressed data for a dynamic block also cannot overwrite the
+ * symbols from which it is being constructed.
+ */
+
+ s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
+ s->pending_buf_size = (ulg)s->lit_bufsize * 4;
@@ -339,4 +375,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
}
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+ s->sym_buf = s->pending_buf + s->lit_bufsize;
+ s->sym_end = (s->lit_bufsize - 1) * 3;
+ /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
@@ -490,3 +530,3 @@ int ZEXPORT deflateResetKeep (strm)
#endif
- s->wrap ? INIT_STATE : BUSY_STATE;
+ INIT_STATE;
strm->adler =
@@ -496,3 +536,3 @@ int ZEXPORT deflateResetKeep (strm)
adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
+ s->last_flush = -2;
@@ -551,3 +591,4 @@ int ZEXPORT deflatePrime (strm, bits, value)
s = strm->state;
- if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+ if (bits < 0 || bits > 16 ||
+ s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR;
@@ -589,3 +630,3 @@ int ZEXPORT deflateParams(strm, level, strategy)
if ((strategy != s->strategy || func != configuration_table[level].func) &&
- s->high_water) {
+ s->last_flush != -2) {
/* Flush the last buffer: */
@@ -594,3 +635,3 @@ int ZEXPORT deflateParams(strm, level, strategy)
return err;
- if (strm->avail_out == 0)
+ if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)
return Z_BUF_ERROR;
@@ -813,2 +854,4 @@ int ZEXPORT deflate (strm, flush)
/* Write the header */
+ if (s->status == INIT_STATE && s->wrap == 0)
+ s->status = BUSY_STATE;
if (s->status == INIT_STATE) {
@@ -1110,3 +1153,2 @@ int ZEXPORT deflateCopy (dest, source)
deflate_state *ss;
- ushf *overlay;
@@ -1130,4 +1172,3 @@ int ZEXPORT deflateCopy (dest, source)
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
+ ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
@@ -1145,4 +1186,3 @@ int ZEXPORT deflateCopy (dest, source)
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+ ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
@@ -1515,2 +1555,4 @@ local void fill_window(s)
s->block_start -= (long) wsize;
+ if (s->insert > s->strstart)
+ s->insert = s->strstart;
slide_hash(s);
@@ -1744,2 +1786,3 @@ local block_state deflate_stored(s, flush)
s->strstart = s->w_size;
+ s->insert = s->strstart;
}
@@ -1752,2 +1795,4 @@ local block_state deflate_stored(s, flush)
s->matches++; /* add a pending slide_hash() */
+ if (s->insert > s->strstart)
+ s->insert = s->strstart;
}
@@ -1755,5 +1800,5 @@ local block_state deflate_stored(s, flush)
s->strstart += used;
+ s->insert += MIN(used, s->w_size - s->insert);
}
s->block_start = s->strstart;
- s->insert += MIN(used, s->w_size - s->insert);
}
@@ -1772,3 +1817,3 @@ local block_state deflate_stored(s, flush)
/* Fill the window with any remaining input. */
- have = s->window_size - s->strstart - 1;
+ have = s->window_size - s->strstart;
if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
@@ -1781,2 +1826,4 @@ local block_state deflate_stored(s, flush)
have += s->w_size; /* more space now */
+ if (s->insert > s->strstart)
+ s->insert = s->strstart;
}
@@ -1787,2 +1834,3 @@ local block_state deflate_stored(s, flush)
s->strstart += have;
+ s->insert += MIN(have, s->w_size - s->insert);
}
@@ -1914,3 +1962,3 @@ local block_state deflate_fast(s, flush)
}
- if (s->last_lit)
+ if (s->sym_next)
FLUSH_BLOCK(s, 0);
@@ -2045,3 +2093,3 @@ local block_state deflate_slow(s, flush)
}
- if (s->last_lit)
+ if (s->sym_next)
FLUSH_BLOCK(s, 0);
@@ -2120,3 +2168,3 @@ local block_state deflate_rle(s, flush)
}
- if (s->last_lit)
+ if (s->sym_next)
FLUSH_BLOCK(s, 0);
@@ -2159,3 +2207,3 @@ local block_state deflate_huff(s, flush)
}
- if (s->last_lit)
+ if (s->sym_next)
FLUSH_BLOCK(s, 0);