diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-14 12:57:57 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-14 12:57:57 +0000 |
commit | 781212c1c1b037543d0c2b689ffde42eb1ac33fc (patch) | |
tree | 3412fa60ddeb5bba10e2b6486076a99da9bc8f8e /decompress_lunzip.c | |
parent | Initial commit. (diff) | |
download | xlunzip-781212c1c1b037543d0c2b689ffde42eb1ac33fc.tar.xz xlunzip-781212c1c1b037543d0c2b689ffde42eb1ac33fc.zip |
Adding upstream version 0.8.upstream/0.8upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'decompress_lunzip.c')
-rw-r--r-- | decompress_lunzip.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/decompress_lunzip.c b/decompress_lunzip.c new file mode 100644 index 0000000..3425997 --- /dev/null +++ b/decompress_lunzip.c @@ -0,0 +1,99 @@ +/* + * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd + * + * Copyright (C) 2016-2024 Antonio Diaz Diaz. + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#ifdef STATIC +#define PREBOOT +#include "lzip_decompress.c" +#else +#include "linux_lzip.h" +#include "linux_lunzip.h" +#include "linux_mm.h" +#endif + +STATIC int INIT __lunzip(unsigned char *inbuf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *outbuf, long out_size, + long *in_posp, long *out_posp, + void (*error)(char *x)) +{ + const int retval = lzip_decompress(inbuf, in_len, fill, flush, + outbuf, out_size, in_posp, out_posp); + switch (retval) { + case 0: break; + case LZIP_OOM_INBUF: + error("Out of memory while allocating input buffer."); + break; + case LZIP_HEADER1_EOF: + error("File ends unexpectedly at member header."); + break; + case LZIP_HEADER2_EOF: + error("Truncated header in multimember file."); + break; + case LZIP_BAD_MAGIC1: + error("Bad magic number (file not in lzip format)."); + break; + case LZIP_BAD_MAGIC2: + error("Corrupt header in multimember file."); + break; + case LZIP_BAD_VERSION: + error("Version of lzip member format not supported."); + break; + case LZIP_BAD_DICT_SIZE: + error("Invalid dictionary size in member header."); + break; + case LZIP_OOM_OUTBUF: + error("Out of memory while allocating output buffer."); + break; + case LZIP_WRITE_ERROR: + error("Write error."); + break; + case LZIP_BAD_DATA: + error("LZIP-compressed data is corrupt."); + break; + case LZIP_DATA_EOF: + error("LZIP-compressed data ends unexpectedly."); + break; + case LZIP_BAD_CRC: + error("CRC mismatch in LZIP-compressed data."); + break; + default: error("Bug in the LZIP decompressor."); + } + return retval; +} + +#ifndef PREBOOT +/* decompress_fn (see include/linux/decompress/generic.h) should have an + * out_size argument to prevent overflowing outbuf in case of corruption + * of the compressed data. + */ +STATIC int INIT lunzip(unsigned char *inbuf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *outbuf, + long *in_posp, + void (*error)(char *x)) +{ + return __lunzip(inbuf, in_len, fill, flush, outbuf, LONG_MAX, + in_posp, 0, error); +} +#else +STATIC int INIT __decompress(unsigned char *inbuf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *outbuf, long out_size, + long *in_posp, + void (*error)(char *x)) +{ +/* Some archs pass out_size = 0 (to mean unlimited size), which is unsafe + * in case of corruption of the compressed data. + */ + return __lunzip(inbuf, in_len - 4, fill, flush, outbuf, + out_size ? out_size : LONG_MAX, in_posp, 0, error); +} +#endif |