Fix lz4 legacy on LG zImages

This commit is contained in:
topjohnwu 2017-10-13 00:18:40 +08:00
parent ce3f3b09b4
commit 2a8898e7c3

View File

@ -5,6 +5,7 @@
#include <lzma.h> #include <lzma.h>
#include <lz4.h> #include <lz4.h>
#include <lz4frame.h> #include <lz4frame.h>
#include <lz4hc.h>
#include <bzlib.h> #include <bzlib.h>
#include "magiskboot.h" #include "magiskboot.h"
@ -37,8 +38,6 @@ size_t gzip(int mode, int fd, const void *buf, size_t size) {
case 1: case 1:
ret = deflateInit2(&strm, 9, Z_DEFLATED, windowBits | ZLIB_GZIP, memLevel, Z_DEFAULT_STRATEGY); ret = deflateInit2(&strm, 9, Z_DEFLATED, windowBits | ZLIB_GZIP, memLevel, Z_DEFAULT_STRATEGY);
break; break;
default:
LOGE("Unsupported gzip mode!\n");
} }
if (ret != Z_OK) if (ret != Z_OK)
@ -98,7 +97,7 @@ size_t lzma(int mode, int fd, const void *buf, size_t size) {
unsigned char out[BUFSIZ]; unsigned char out[BUFSIZ];
// Initialize preset // Initialize preset
lzma_lzma_preset(&opt, LZMA_PRESET_DEFAULT); lzma_lzma_preset(&opt, 9);
lzma_filter filters[] = { lzma_filter filters[] = {
{ .id = LZMA_FILTER_LZMA2, .options = &opt }, { .id = LZMA_FILTER_LZMA2, .options = &opt },
{ .id = LZMA_VLI_UNKNOWN, .options = NULL }, { .id = LZMA_VLI_UNKNOWN, .options = NULL },
@ -114,8 +113,6 @@ size_t lzma(int mode, int fd, const void *buf, size_t size) {
case 2: case 2:
ret = lzma_alone_encoder(&strm, &opt); ret = lzma_alone_encoder(&strm, &opt);
break; break;
default:
LOGE("Unsupported lzma mode!\n");
} }
@ -168,8 +165,6 @@ size_t lz4(int mode, int fd, const void *buf, size_t size) {
case 1: case 1:
ret = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION); ret = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION);
break; break;
default:
LOGE("Unsupported lz4 mode!\n");
} }
if (LZ4F_isError(ret)) if (LZ4F_isError(ret))
@ -283,8 +278,6 @@ size_t bzip2(int mode, int fd, const void* buf, size_t size) {
case 1: case 1:
ret = BZ2_bzCompressInit(&strm, 9, 0, 0); ret = BZ2_bzCompressInit(&strm, 9, 0, 0);
break; break;
default:
LOGE("Unsupported bzip2 mode!\n");
} }
if (ret != BZ_OK) if (ret != BZ_OK)
@ -333,11 +326,10 @@ size_t bzip2(int mode, int fd, const void* buf, size_t size) {
// Mode: 0 = decode; 1 = encode // Mode: 0 = decode; 1 = encode
size_t lz4_legacy(int mode, int fd, const void* buf, size_t size) { size_t lz4_legacy(int mode, int fd, const void* buf, size_t size) {
size_t pos = 0, total = 0; size_t pos = 0;
int have; int have;
char *out; char *out;
unsigned block_size, insize; unsigned block_size, insize, total = 0;
unsigned char block_size_le[4];
switch(mode) { switch(mode) {
case 0: case 0:
@ -350,22 +342,17 @@ size_t lz4_legacy(int mode, int fd, const void* buf, size_t size) {
// Write magic // Write magic
total += xwrite(fd, "\x02\x21\x4c\x18", 4); total += xwrite(fd, "\x02\x21\x4c\x18", 4);
break; break;
default:
LOGE("Unsupported lz4_legacy mode!\n");
} }
do { do {
const char *buff = buf;
switch(mode) { switch(mode) {
case 0: case 0:
block_size = buff[pos]; // Read block size
block_size += (buff[pos + 1]<<8); block_size = *(unsigned *)(buf + pos);
block_size += (buff[pos + 2]<<16);
block_size += ((unsigned)buff[pos + 3])<<24;
pos += 4; pos += 4;
if (block_size > LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE)) if (block_size > LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE))
LOGE("lz4_legacy block size too large!\n"); goto done;
have = LZ4_decompress_safe((const char*) (buf + pos), out, block_size, LZ4_LEGACY_BLOCKSIZE); have = LZ4_decompress_safe(buf + pos, out, block_size, LZ4_LEGACY_BLOCKSIZE);
if (have < 0) if (have < 0)
LOGE("Cannot decode lz4_legacy block\n"); LOGE("Cannot decode lz4_legacy block\n");
pos += block_size; pos += block_size;
@ -375,21 +362,24 @@ size_t lz4_legacy(int mode, int fd, const void* buf, size_t size) {
insize = size - pos; insize = size - pos;
else else
insize = LZ4_LEGACY_BLOCKSIZE; insize = LZ4_LEGACY_BLOCKSIZE;
have = LZ4_compress_default((const char*) (buf + pos), out, insize, LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE)); have = LZ4_compress_HC(buf + pos, out, insize, LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE), 9);
if (have == 0) if (have == 0)
LOGE("lz4_legacy compression error\n"); LOGE("lz4_legacy compression error\n");
pos += insize; pos += insize;
block_size_le[0] = have & 0xff; // Write block size
block_size_le[1] = (have >> 8) & 0xff; total += xwrite(fd, &have, sizeof(have));
block_size_le[2] = (have >> 16) & 0xff;
block_size_le[3] = (have >> 24) & 0xff;
total += xwrite(fd, block_size_le, 4);
break; break;
} }
// Write main data // Write main data
total += xwrite(fd, out, have); total += xwrite(fd, out, have);
} while(pos < size); } while(pos < size);
done:
if (mode == 1) {
// Append original size to output
unsigned uncomp = size;
xwrite(fd, &uncomp, sizeof(uncomp));
}
free(out); free(out);
return total; return total;
} }