diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2018-08-26 07:57:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2018-08-26 07:57:14 +0000 |
commit | b9c3804bd95fa4adf48dd177743ccedf6f35b321 (patch) | |
tree | 742dfd2b9b12f5a22f8deb808697300440230305 /decompress_lunzip.c | |
parent | Initial commit. (diff) | |
download | xlunzip-b9c3804bd95fa4adf48dd177743ccedf6f35b321.tar.xz xlunzip-b9c3804bd95fa4adf48dd177743ccedf6f35b321.zip |
Adding upstream version 0.3.upstream/0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'decompress_lunzip.c')
-rw-r--r-- | decompress_lunzip.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/decompress_lunzip.c b/decompress_lunzip.c new file mode 100644 index 0000000..106c95b --- /dev/null +++ b/decompress_lunzip.c @@ -0,0 +1,100 @@ +/* + * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd + * + * Copyright (C) 2016-2018 Antonio Diaz Diaz. + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#ifdef STATIC +#define PREBOOT +#include "lzip.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 linux/decompress/generic.h) should have an out_size + * argument to prevent overrunning 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 |