Skip to content

Commit 43b2703

Browse files
mtl1979Dead2
authored andcommitted
Fix shift overflow in inflate and send_code.
1 parent 287c4dc commit 43b2703

4 files changed

Lines changed: 16 additions & 12 deletions

File tree

infback.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ int32_t Z_EXPORT PREFIX(inflateBackInit_)(PREFIX3(stream) *strm, int32_t windowB
102102
do { \
103103
PULL(); \
104104
have--; \
105-
hold += ((unsigned)(*next++) << bits); \
105+
hold += ((uint64_t)(*next++) << bits); \
106106
bits += 8; \
107107
} while (0)
108108

@@ -154,7 +154,7 @@ int32_t Z_EXPORT PREFIX(inflateBack)(PREFIX3(stream) *strm, in_func in, void *in
154154
z_const unsigned char *next; /* next input */
155155
unsigned char *put; /* next output */
156156
unsigned have, left; /* available input and output */
157-
uint32_t hold; /* bit buffer */
157+
uint64_t hold; /* bit buffer */
158158
unsigned bits; /* bits in bit buffer */
159159
unsigned copy; /* number of stored or match bytes to copy */
160160
unsigned char *from; /* where to copy match bytes from */

inflate.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ int32_t Z_EXPORT PREFIX(inflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32
291291
if (bits > 16 || state->bits + (unsigned int)bits > 32)
292292
return Z_STREAM_ERROR;
293293
value &= (1L << bits) - 1;
294-
state->hold += (unsigned)value << state->bits;
294+
state->hold += (uint64_t)value << state->bits;
295295
state->bits += (unsigned int)bits;
296296
return Z_OK;
297297
}
@@ -387,7 +387,7 @@ static void updatewindow(PREFIX3(stream) *strm, const uint8_t *end, uint32_t len
387387
do { \
388388
if (have == 0) goto inf_leave; \
389389
have--; \
390-
hold += ((unsigned)(*next++) << bits); \
390+
hold += ((uint64_t)(*next++) << bits); \
391391
bits += 8; \
392392
} while (0)
393393

@@ -479,7 +479,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
479479
unsigned char *put; /* next output */
480480
unsigned char *from; /* where to copy match bytes from */
481481
unsigned have, left; /* available input and output */
482-
uint32_t hold; /* bit buffer */
482+
uint64_t hold; /* bit buffer */
483483
unsigned bits; /* bits in bit buffer */
484484
uint32_t in, out; /* save starting available input and output */
485485
unsigned copy; /* number of stored or match bytes to copy */
@@ -577,7 +577,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
577577
case TIME:
578578
NEEDBITS(32);
579579
if (state->head != NULL)
580-
state->head->time = hold;
580+
state->head->time = (unsigned)(hold);
581581
if ((state->flags & 0x0200) && (state->wrap & 4))
582582
CRC4(state->check, hold);
583583
INITBITS();
@@ -704,7 +704,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
704704
#endif
705705
case DICTID:
706706
NEEDBITS(32);
707-
strm->adler = state->check = ZSWAP32(hold);
707+
strm->adler = state->check = ZSWAP32((unsigned)hold);
708708
INITBITS();
709709
state->mode = DICT;
710710
Z_FALLTHROUGH;
@@ -1128,7 +1128,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
11281128
#ifdef GUNZIP
11291129
state->flags ? hold :
11301130
#endif
1131-
ZSWAP32(hold)) != state->check) {
1131+
ZSWAP32((unsigned)hold)) != state->check) {
11321132
SET_BAD("incorrect data check");
11331133
break;
11341134
}

inflate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ struct ALIGNED_(64) inflate_state {
121121
uint32_t chunksize; /* size of memory copying chunk */
122122

123123
/* bit accumulator */
124-
uint32_t hold; /* input bit accumulator */
124+
uint64_t hold; /* input bit accumulator */
125125
unsigned bits; /* number of bits in "in" */
126126
/* fixed and dynamic code tables */
127127
unsigned lenbits; /* index bits for lencode */
@@ -141,7 +141,7 @@ struct ALIGNED_(64) inflate_state {
141141
code *next; /* next available space in codes[] */
142142

143143
#if defined(_M_IX86) || defined(_M_ARM)
144-
uint32_t padding[2];
144+
uint32_t padding[1];
145145
#endif
146146
struct crc32_fold_s ALIGNED_(16) crc_fold;
147147

trees_emit.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,21 @@ extern Z_INTERNAL const int base_dist[D_CODES];
3838
/* If not enough room in bi_buf, use (valid) bits from bi_buf and
3939
* (64 - bi_valid) bits from value, leaving (width - (64-bi_valid))
4040
* unused bits in value.
41+
*
42+
* NOTE: Static analyzers can't evaluate value of total_bits, so we
43+
* also need to make sure bi_valid is within acceptable range,
44+
* otherwise the shifts will overflow.
4145
*/
4246
#define send_bits(s, t_val, t_len, bi_buf, bi_valid) {\
4347
uint64_t val = (uint64_t)t_val;\
4448
uint32_t len = (uint32_t)t_len;\
4549
uint32_t total_bits = bi_valid + len;\
4650
send_bits_trace(s, val, len);\
4751
sent_bits_add(s, len);\
48-
if (total_bits < BIT_BUF_SIZE) {\
52+
if (total_bits < BIT_BUF_SIZE && bi_valid < BIT_BUF_SIZE) {\
4953
bi_buf |= val << bi_valid;\
5054
bi_valid = total_bits;\
51-
} else if (bi_valid == BIT_BUF_SIZE) {\
55+
} else if (bi_valid >= BIT_BUF_SIZE) {\
5256
put_uint64(s, bi_buf);\
5357
bi_buf = val;\
5458
bi_valid = len;\

0 commit comments

Comments
 (0)