#include <malloc.h>
#include <linux/lzo.h>
#include <linux/zstd.h>
+#include <linux/compat.h>
#include <u-boot/zlib.h>
#include <asm/unaligned.h>
#define LZO_LEN 4
static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
{
- u32 tot_len, in_len, res;
+ u32 tot_len, tot_in, in_len, res;
size_t out_len;
int ret;
return -1;
tot_len = le32_to_cpu(get_unaligned((u32 *)cbuf));
+ tot_in = 0;
cbuf += LZO_LEN;
clen -= LZO_LEN;
tot_len -= LZO_LEN;
+ tot_in += LZO_LEN;
if (tot_len == 0 && dlen)
return -1;
res = 0;
while (tot_len > LZO_LEN) {
+ u32 rem_page;
+
in_len = le32_to_cpu(get_unaligned((u32 *)cbuf));
cbuf += LZO_LEN;
clen -= LZO_LEN;
return -1;
tot_len -= (LZO_LEN + in_len);
+ tot_in += (LZO_LEN + in_len);
out_len = dlen;
ret = lzo1x_decompress_safe(cbuf, in_len, dbuf, &out_len);
dlen -= out_len;
res += out_len;
+
+ /*
+ * If the 4 bytes header does not fit to the rest of the page we
+ * have to move to next one, or we read some garbage.
+ */
+ rem_page = PAGE_SIZE - (tot_in % PAGE_SIZE);
+ if (rem_page < LZO_LEN) {
+ cbuf += rem_page;
+ tot_in += rem_page;
+ clen -= rem_page;
+ tot_len -= rem_page;
+ }
}
return res;