Skip to content

Commit

Permalink
Merge pull request #37 from 0xPhoeniX/lzma_support
Browse files Browse the repository at this point in the history
Support for LZMA legacy images
  • Loading branch information
DrDaveD authored Jun 28, 2023
2 parents 7830e50 + cec7f2a commit 30470af
Showing 1 changed file with 72 additions and 5 deletions.
77 changes: 72 additions & 5 deletions decompress.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "decompress.h"

#include "squashfs_fs.h"
#include "swap.h"

#include <string.h>

Expand Down Expand Up @@ -65,6 +66,66 @@ static sqfs_err sqfs_decompressor_xz(void *in, size_t insz,
return SQFS_OK;
}
#define CAN_DECOMPRESS_XZ 1

// The following implementation was adapted from squashfs-tools
// https://github.com/plougher/squashfs-tools.git

#define LZMA_PROPS_SIZE 5
#define LZMA_UNCOMP_SIZE 8
#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + LZMA_UNCOMP_SIZE)
#define MEMLIMIT (32 * 1024 * 1024)

static sqfs_err sqfs_decompressor_lzma(void *in, size_t insz,
void *out, size_t *outsz) {

lzma_stream strm = LZMA_STREAM_INIT;
uint32_t uncompressed_size = 0, res;
unsigned char lzma_header[LZMA_HEADER_SIZE];

res = lzma_alone_decoder(&strm, MEMLIMIT);
if (res != LZMA_OK) {
lzma_end(&strm);
return SQFS_ERR;
}

memcpy(lzma_header, in, LZMA_HEADER_SIZE);
uncompressed_size = *((uint32_t*)(lzma_header + LZMA_PROPS_SIZE));
sqfs_swapin32(&uncompressed_size);

if (uncompressed_size > *outsz) {
lzma_end(&strm);
return SQFS_ERR;
}

memset(lzma_header + LZMA_PROPS_SIZE, 255, LZMA_UNCOMP_SIZE);

strm.next_out = out;
strm.avail_out = *outsz;
strm.next_in = lzma_header;
strm.avail_in = LZMA_HEADER_SIZE;

res = lzma_code(&strm, LZMA_RUN);

if (res != LZMA_OK || strm.avail_in != 0) {
lzma_end(&strm);
return SQFS_ERR;
}

strm.next_in = (uint8_t *)in + LZMA_HEADER_SIZE;
strm.avail_in = insz - LZMA_HEADER_SIZE;

res = lzma_code(&strm, LZMA_FINISH);
lzma_end(&strm);

if (res == LZMA_STREAM_END || (res == LZMA_OK &&
strm.total_out >= uncompressed_size && strm.avail_in == 0)) {
*outsz = uncompressed_size;
return SQFS_OK;
}

return SQFS_ERR;
}
#define CAN_DECOMPRESS_LZMA 1
#endif


Expand Down Expand Up @@ -116,12 +177,15 @@ sqfs_decompressor sqfs_decompressor_get(sqfs_compression_type type) {
#ifdef CAN_DECOMPRESS_ZLIB
case ZLIB_COMPRESSION: return &sqfs_decompressor_zlib;
#endif
#ifdef CAN_DECOMPRESS_XZ
case XZ_COMPRESSION: return &sqfs_decompressor_xz;
#ifdef CAN_DECOMPRESS_LZMA
case LZMA_COMPRESSION: return &sqfs_decompressor_lzma;
#endif
#ifdef CAN_DECOMPRESS_LZO
case LZO_COMPRESSION: return &sqfs_decompressor_lzo;
#endif
#ifdef CAN_DECOMPRESS_XZ
case XZ_COMPRESSION: return &sqfs_decompressor_xz;
#endif
#ifdef CAN_DECOMPRESS_LZ4
case LZ4_COMPRESSION: return &sqfs_decompressor_lz4;
#endif
Expand All @@ -145,15 +209,18 @@ char *sqfs_compression_name(sqfs_compression_type type) {
void sqfs_compression_supported(sqfs_compression_type *types) {
size_t i = 0;
memset(types, SQFS_COMP_UNKNOWN, SQFS_COMP_MAX * sizeof(*types));
#ifdef CAN_DECOMPRESS_ZLIB
types[i++] = ZLIB_COMPRESSION;
#endif
#ifdef CAN_DECOMPRESS_LZMA
types[i++] = LZMA_COMPRESSION;
#endif
#ifdef CAN_DECOMPRESS_LZO
types[i++] = LZO_COMPRESSION;
#endif
#ifdef CAN_DECOMPRESS_XZ
types[i++] = XZ_COMPRESSION;
#endif
#ifdef CAN_DECOMPRESS_ZLIB
types[i++] = ZLIB_COMPRESSION;
#endif
#ifdef CAN_DECOMPRESS_LZ4
types[i++] = LZ4_COMPRESSION;
#endif
Expand Down

0 comments on commit 30470af

Please sign in to comment.