Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize)
{
	size_t inPos = 0, outPos = 0;
	const uint8_t *buf0, *buf1, *buf2, *buf3;
	size_t size0, size1, size2, size3;
	const uint8_t *buffer, *bufferLim;
	unsigned int i, j;

	size0 = zip->tmp_stream_bytes_remaining;
	buf0 = zip->tmp_stream_buff + zip->tmp_stream_bytes_avail - size0;
	size1 = zip->sub_stream_bytes_remaining[0];
	buf1 = zip->sub_stream_buff[0] + zip->sub_stream_size[0] - size1;
	size2 = zip->sub_stream_bytes_remaining[1];
	buf2 = zip->sub_stream_buff[1] + zip->sub_stream_size[1] - size2;
	size3 = zip->sub_stream_bytes_remaining[2];
	buf3 = zip->sub_stream_buff[2] + zip->sub_stream_size[2] - size3;

	buffer = buf3;
	bufferLim = buffer + size3;

	if (zip->bcj_state == 0) {
		/*
		 * Initialize.
		 */
		zip->bcj2_prevByte = 0;
		for (i = 0;
		    i < sizeof(zip->bcj2_p) / sizeof(zip->bcj2_p[0]); i++)
			zip->bcj2_p[i] = kBitModelTotal >> 1;
		RC_INIT2;
		zip->bcj_state = 1;
	}

	/*
	 * Gather the odd bytes of a previous call.
	 */
	for (i = 0; zip->odd_bcj_size > 0 && outPos < outSize; i++) {
		outBuf[outPos++] = zip->odd_bcj[i];
		zip->odd_bcj_size--;
	}

	if (outSize == 0) {
		zip->bcj2_outPos += outPos;
		return (outPos);
	}

	for (;;) {
		uint8_t b;
		CProb *prob;
		uint32_t bound;
		uint32_t ttt;

		size_t limit = size0 - inPos;
		if (outSize - outPos < limit)
			limit = outSize - outPos;

		if (zip->bcj_state == 1) {
			while (limit != 0) {
				uint8_t bb = buf0[inPos];
				outBuf[outPos++] = bb;
				if (IsJ(zip->bcj2_prevByte, bb)) {
					zip->bcj_state = 2;
					break;
				}
				inPos++;
				zip->bcj2_prevByte = bb;
				limit--;
			}
		}

		if (limit == 0 || outPos == outSize)
			break;
		zip->bcj_state = 1;

		b = buf0[inPos++];

		if (b == 0xE8)
			prob = zip->bcj2_p + zip->bcj2_prevByte;
		else if (b == 0xE9)
			prob = zip->bcj2_p + 256;
		else
			prob = zip->bcj2_p + 257;

		IF_BIT_0(prob) {
			UPDATE_0(prob)
			zip->bcj2_prevByte = b;
		} else {
			uint32_t dest;
			const uint8_t *v;
			uint8_t out[4];

			UPDATE_1(prob)
			if (b == 0xE8) {
				v = buf1;
				if (size1 < 4)
					return SZ_ERROR_DATA;
				buf1 += 4;
				size1 -= 4;
			} else {
				v = buf2;
				if (size2 < 4)
					return SZ_ERROR_DATA;
				buf2 += 4;
				size2 -= 4;
			}
			dest = (((uint32_t)v[0] << 24) |
			    ((uint32_t)v[1] << 16) |
			    ((uint32_t)v[2] << 8) |
			    ((uint32_t)v[3])) -
			    ((uint32_t)zip->bcj2_outPos + (uint32_t)outPos + 4);
			out[0] = (uint8_t)dest;
			out[1] = (uint8_t)(dest >> 8);
			out[2] = (uint8_t)(dest >> 16);
			out[3] = zip->bcj2_prevByte = (uint8_t)(dest >> 24);

			for (i = 0; i < 4 && outPos < outSize; i++)
				outBuf[outPos++] = out[i];
			if (i < 4) {
				/*
				 * Save odd bytes which we could not add into
				 * the output buffer because of out of space.
				 */
				zip->odd_bcj_size = 4 -i;
				for (; i < 4; i++) {
					j = i - 4 + (unsigned)zip->odd_bcj_size;
					zip->odd_bcj[j] = out[i];
				}
				break;
			}
		}
	}
	zip->tmp_stream_bytes_remaining -= inPos;
	zip->sub_stream_bytes_remaining[0] = size1;
	zip->sub_stream_bytes_remaining[1] = size2;
	zip->sub_stream_bytes_remaining[2] = bufferLim - buffer;
	zip->bcj2_outPos += outPos;

	return ((ssize_t)outPos);
}

The product performs a calculation that can produce an integer overflow or wraparound when the logic assumes that the resulting value will always be larger than the original value. This occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may become a very small or negative number.