/* gcc -I`pwd` LzmaDec.c test.c -o test ./test LzmaDecode() calling logic borrowed from https://github.com/u-boot/u-boot/blob/master/lib/lzma/LzmaTools.c#L108 */ #include #include #include #include #include #include #include #include "sys/stat.h" #include #include "LzmaDec.h" #include "7zVersion.h" #define LZMA_SIZE_OFFSET LZMA_PROPS_SIZE #define LZMA_DATA_OFFSET LZMA_SIZE_OFFSET+sizeof(uint64_t) static void *SzAlloc(const ISzAlloc *p, size_t size) { return malloc(size); } static void SzFree(const ISzAlloc *p, void *address) { free(address); } int get_file(const char * filename, void **addr){ int fd, ret; size_t len_file, len; struct stat st; ELzmaStatus state; memset(&state, 0, sizeof(state)); if ((fd = open(filename, O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH)) < 0){ perror("Error in file opening"); return -1; } if ((ret = fstat(fd, &st)) < 0){ perror("Error in fstat"); return -1; } len_file = st.st_size; if ((*addr = mmap(NULL, len_file, PROT_READ, MAP_SHARED,fd,0)) == MAP_FAILED){ perror("Error in mmap"); return -1; } return 0; } void main(){ char *src, *dst; size_t uncompressedSize, compressedSize; size_t outProcessed; ELzmaStatus state; ISzAlloc g_Alloc; memset(&state, 0, sizeof(state)); g_Alloc.Alloc = SzAlloc; g_Alloc.Free = SzFree; if (get_file("/tmp/bad_test.lzma", (void**)&src) == -1) { return; } // read value from LZMA header uncompressedSize = *(uint64_t *)(&src[LZMA_SIZE_OFFSET]); printf("uncompressed size: 0x%lx\n", uncompressedSize); // set to max size_t, as it was done in U-Boot here with `dst_len` - https://github.com/u-boot/u-boot/blob/master/cmd/lzmadec.c#L24 compressedSize = ~0UL; // this is followed by a subtract of props size - https://github.com/u-boot/u-boot/blob/master/lib/lzma/LzmaTools.c#L51 compressedSize = (compressedSize - LZMA_PROPS_SIZE); printf("compressed size: 0x%lx\n", compressedSize); printf("7z Release: %s\n", MY_VERSION); LzmaDecode( dst, &uncompressedSize, src + LZMA_DATA_OFFSET, &compressedSize, src, LZMA_PROPS_SIZE, LZMA_FINISH_END, &state, &g_Alloc); }