|
@@ -83,13 +83,20 @@ STATIC inline int INIT unlz4(u8 *input, int in_len,
|
|
|
if (posp)
|
|
|
*posp = 0;
|
|
|
|
|
|
- if (fill)
|
|
|
- fill(inp, 4);
|
|
|
+ if (fill) {
|
|
|
+ size = fill(inp, 4);
|
|
|
+ if (size < 4) {
|
|
|
+ error("data corrupted");
|
|
|
+ goto exit_2;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
chunksize = get_unaligned_le32(inp);
|
|
|
if (chunksize == ARCHIVE_MAGICNUMBER) {
|
|
|
- inp += 4;
|
|
|
- size -= 4;
|
|
|
+ if (!fill) {
|
|
|
+ inp += 4;
|
|
|
+ size -= 4;
|
|
|
+ }
|
|
|
} else {
|
|
|
error("invalid header");
|
|
|
goto exit_2;
|
|
@@ -100,29 +107,44 @@ STATIC inline int INIT unlz4(u8 *input, int in_len,
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
- if (fill)
|
|
|
- fill(inp, 4);
|
|
|
+ if (fill) {
|
|
|
+ size = fill(inp, 4);
|
|
|
+ if (size == 0)
|
|
|
+ break;
|
|
|
+ if (size < 4) {
|
|
|
+ error("data corrupted");
|
|
|
+ goto exit_2;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
chunksize = get_unaligned_le32(inp);
|
|
|
if (chunksize == ARCHIVE_MAGICNUMBER) {
|
|
|
- inp += 4;
|
|
|
- size -= 4;
|
|
|
+ if (!fill) {
|
|
|
+ inp += 4;
|
|
|
+ size -= 4;
|
|
|
+ }
|
|
|
if (posp)
|
|
|
*posp += 4;
|
|
|
continue;
|
|
|
}
|
|
|
- inp += 4;
|
|
|
- size -= 4;
|
|
|
+
|
|
|
|
|
|
if (posp)
|
|
|
*posp += 4;
|
|
|
|
|
|
- if (fill) {
|
|
|
+ if (!fill) {
|
|
|
+ inp += 4;
|
|
|
+ size -= 4;
|
|
|
+ } else {
|
|
|
if (chunksize > lz4_compressbound(uncomp_chunksize)) {
|
|
|
error("chunk length is longer than allocated");
|
|
|
goto exit_2;
|
|
|
}
|
|
|
- fill(inp, chunksize);
|
|
|
+ size = fill(inp, chunksize);
|
|
|
+ if (size < chunksize) {
|
|
|
+ error("data corrupted");
|
|
|
+ goto exit_2;
|
|
|
+ }
|
|
|
}
|
|
|
#ifdef PREBOOT
|
|
|
if (out_len >= uncomp_chunksize) {
|
|
@@ -149,18 +171,17 @@ STATIC inline int INIT unlz4(u8 *input, int in_len,
|
|
|
if (posp)
|
|
|
*posp += chunksize;
|
|
|
|
|
|
- size -= chunksize;
|
|
|
+ if (!fill) {
|
|
|
+ size -= chunksize;
|
|
|
|
|
|
- if (size == 0)
|
|
|
- break;
|
|
|
- else if (size < 0) {
|
|
|
- error("data corrupted");
|
|
|
- goto exit_2;
|
|
|
+ if (size == 0)
|
|
|
+ break;
|
|
|
+ else if (size < 0) {
|
|
|
+ error("data corrupted");
|
|
|
+ goto exit_2;
|
|
|
+ }
|
|
|
+ inp += chunksize;
|
|
|
}
|
|
|
-
|
|
|
- inp += chunksize;
|
|
|
- if (fill)
|
|
|
- inp = inp_start;
|
|
|
}
|
|
|
|
|
|
ret = 0;
|