unsigned char *start = dst;
const unsigned char *send = src + src_len;
u32 slen, dlen;
- size_t tmp;
+ size_t tmp, remaining;
int r;
src = parse_header(src);
if (!src)
return LZO_E_ERROR;
+ remaining = *dst_len;
while (src < send) {
/* read uncompressed block size */
dlen = get_unaligned_be32(src);
if (slen <= 0 || slen > dlen)
return LZO_E_ERROR;
+ /* abort if buffer ran out of room */
+ if (dlen > remaining)
+ return LZO_E_OUTPUT_OVERRUN;
+
/* decompress */
tmp = dlen;
r = lzo1x_decompress_safe((u8 *) src, slen, dst, &tmp);
- if (r != LZO_E_OK)
+ if (r != LZO_E_OK) {
+ *dst_len = dst - start;
return r;
+ }
if (dlen != tmp)
return LZO_E_ERROR;
src += slen;
dst += dlen;
+ remaining -= dlen;
}
return LZO_E_INPUT_OVERRUN;