gunzip: fix incorrect decoding of "fixed" inflate blocks
function old new delta huft_build 1008 1022 +14 inflate_block 1253 1256 +3 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 17/0) Total: 17 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
		| @@ -280,11 +280,17 @@ static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current | ||||
|  * b:	code lengths in bits (all assumed <= BMAX) | ||||
|  * n:	number of codes (assumed <= N_MAX) | ||||
|  * s:	number of simple-valued codes (0..s-1) | ||||
|  * d:	list of base values for non-simple codes | ||||
|  * e:	list of extra bits for non-simple codes | ||||
|  * cp_ext->cp,ext: list of base values/extra bits for non-simple codes | ||||
|  * m:	maximum lookup bits, returns actual | ||||
|  * result: starting table | ||||
|  * | ||||
|  * On error, returns a value with lowest-bit set on error. | ||||
|  * It can be just the value of 0x1, | ||||
|  * or a valid pointer to a Huffman table, ORed with 0x1 if incompete table | ||||
|  * is given: "fixed inflate" decoder feeds us such data. | ||||
|  */ | ||||
| #define BAD_HUFT(p) ((uintptr_t)(p) & 1) | ||||
| #define ERR_RET     ((huft_t*)(uintptr_t)1) | ||||
| static huft_t* huft_build(const unsigned *b, const unsigned n, | ||||
| 			const unsigned s, const struct cp_ext *cp_ext, | ||||
| 			unsigned *m) | ||||
| @@ -347,11 +353,11 @@ static huft_t* huft_build(const unsigned *b, const unsigned n, | ||||
| 	for (y = 1 << j; j < i; j++, y <<= 1) { | ||||
| 		y -= c[j]; | ||||
| 		if (y < 0) | ||||
| 			return NULL; /* bad input: more codes than bits */ | ||||
| 			return ERR_RET; /* bad input: more codes than bits */ | ||||
| 	} | ||||
| 	y -= c[i]; | ||||
| 	if (y < 0) | ||||
| 		return NULL; | ||||
| 		return ERR_RET; | ||||
| 	c[i] += y; | ||||
|  | ||||
| 	/* Generate starting offsets into the value table for each length */ | ||||
| @@ -378,7 +384,7 @@ static huft_t* huft_build(const unsigned *b, const unsigned n, | ||||
| 	} while (++i < n); | ||||
|  | ||||
| 	/* Generate the Huffman codes and for each, make the table entries */ | ||||
| 	result = NULL; | ||||
| 	result = ERR_RET; | ||||
| 	t = &result; | ||||
| 	x[0] = i = 0;   /* first Huffman code is zero */ | ||||
| 	p = v;          /* grab values in bit order */ | ||||
| @@ -472,7 +478,8 @@ static huft_t* huft_build(const unsigned *b, const unsigned n, | ||||
| 	*m = ws[1]; | ||||
|  | ||||
| 	if (y != 0 && g != 1) /* we were given an incomplete table */ | ||||
| 		return NULL; | ||||
| 		/* return "result" ORed with 1 */ | ||||
| 		return (void*)((uintptr_t)result | 1); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
| @@ -776,13 +783,16 @@ static int inflate_block(STATE_PARAM smallint *e) | ||||
| 			ll[i] = 8; | ||||
| 		bl = 7; | ||||
| 		inflate_codes_tl = huft_build(ll, 288, 257, &lit, &bl); | ||||
| 		/* huft_build() never returns error here - we use known data */ | ||||
| 		/* ^^^ never returns error here - we use known data */ | ||||
|  | ||||
| 		/* set up distance table */ | ||||
| 		for (i = 0; i < 30; i++) /* make an incomplete code set */ | ||||
| 			ll[i] = 5; | ||||
| 		bd = 5; | ||||
| 		inflate_codes_td = huft_build(ll, 30, 0, &dist, &bd); | ||||
| 		/* ^^^ does return error here! (lsb bit is set) - we gave it incomplete code set */ | ||||
| 		/* clearing error bit: */ | ||||
| 		inflate_codes_td = (void*)((uintptr_t)inflate_codes_td & ~(uintptr_t)1); | ||||
|  | ||||
| 		/* set up data for inflate_codes() */ | ||||
| 		inflate_codes_setup(PASS_STATE bl, bd); | ||||
| @@ -849,7 +859,7 @@ static int inflate_block(STATE_PARAM smallint *e) | ||||
| 		/* build decoding table for trees - single level, 7 bit lookup */ | ||||
| 		bl = 7; | ||||
| 		inflate_codes_tl = huft_build(ll, 19, 19, NULL, &bl); | ||||
| 		if (!inflate_codes_tl) { | ||||
| 		if (BAD_HUFT(inflate_codes_tl)) { | ||||
| 			abort_unzip(PASS_STATE_ONLY);	/* incomplete code set */ | ||||
| 		} | ||||
|  | ||||
| @@ -914,12 +924,12 @@ static int inflate_block(STATE_PARAM smallint *e) | ||||
| 		/* build the decoding tables for literal/length and distance codes */ | ||||
| 		bl = lbits; | ||||
| 		inflate_codes_tl = huft_build(ll, nl, 257, &lit, &bl); | ||||
| 		if (!inflate_codes_tl) { | ||||
| 		if (BAD_HUFT(inflate_codes_tl)) { | ||||
| 			abort_unzip(PASS_STATE_ONLY); | ||||
| 		} | ||||
| 		bd = dbits; | ||||
| 		inflate_codes_td = huft_build(ll + nl, nd, 0, &dist, &bd); | ||||
| 		if (!inflate_codes_td) { | ||||
| 		if (BAD_HUFT(inflate_codes_td)) { | ||||
| 			abort_unzip(PASS_STATE_ONLY); | ||||
| 		} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user