[File] [PATCH] support decompressing lzip archives via lzlib

Christos Zoulas christos at zoulas.com
Thu Sep 15 14:48:16 UTC 2022


On 2022-09-15 5:28 am, Michał Górny wrote:

committed, thanks!

christos
> ---
>  configure.ac   | 19 ++++++++++++
>  src/compress.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 103 insertions(+)
> 
> diff --git a/configure.ac b/configure.ac
> index f6593917..9a0a2250 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -54,6 +54,11 @@ AC_ARG_ENABLE([zstdlib],
>  [AS_HELP_STRING([--disable-zstdlib], [disable zstdlib compression
> support @<:@default=auto@:>@])])
>  AC_MSG_RESULT($enable_zstdlib)
> 
> +AC_MSG_CHECKING(for lzlib support)
> +AC_ARG_ENABLE([lzlib],
> +[AS_HELP_STRING([--disable-lzlib], [disable liblz (lzip) compression
> support @<:@default=auto@:>@])])
> +AC_MSG_RESULT($enable_lzlib)
> +
>  AC_MSG_CHECKING(for libseccomp support)
>  AC_ARG_ENABLE([libseccomp],
>  [AS_HELP_STRING([--disable-libseccomp], [disable libseccomp
> sandboxing @<:@default=auto@:>@])])
> @@ -120,6 +125,9 @@ fi
>  if test "$enable_zstdlib" != "no"; then
>    AC_CHECK_HEADERS(zstd.h zstd_errors.h)
>  fi
> +if test "$enable_lzlib" != "no"; then
> +  AC_CHECK_HEADERS(lzlib.h)
> +fi
>  AC_CHECK_TYPE([sig_t],[AC_DEFINE([HAVE_SIG_T],1,[Have sig_t
> type])],,[#include <signal.h>])
> 
>  dnl Checks for typedefs, structures, and compiler characteristics.
> @@ -191,6 +199,9 @@ fi
>  if test "$enable_zstdlib" != "no"; then
>    AC_CHECK_LIB(zstd, ZSTD_createDStream)
>  fi
> +if test "$enable_lzlib" != "no"; then
> +  AC_CHECK_LIB(lz, LZ_decompress_open)
> +fi
>  if test "$enable_libseccomp" != "no"; then
>      AC_CHECK_LIB(seccomp, seccomp_init)
>  fi
> @@ -234,6 +245,14 @@ fi
>  if  test "$ac_cv_header_zstd_h$ac_cv_lib_zstd_ZSTD_createDStream" =
> "yesyes"; then
>    AC_DEFINE([ZSTDLIBSUPPORT], 1, [Enable zstdlib compression support])
>  fi
> +if test "$enable_lzlib" = "yes"; then
> +  if test "$ac_cv_header_lzlib_h$ac_cv_lib_lz_LZ_decompress_open" !=
> "yesyes"; then
> +    AC_MSG_ERROR([lzlib support requested but not found])
> +  fi
> +fi
> +if  test "$ac_cv_header_lzlib_h$ac_cv_lib_lz_LZ_decompress_open" =
> "yesyes"; then
> +  AC_DEFINE([LZLIBSUPPORT], 1, [Enable lzlib compression support])
> +fi
> 
>  AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile tests/Makefile
> doc/Makefile python/Makefile libmagic.pc])
>  AC_OUTPUT
> diff --git a/src/compress.c b/src/compress.c
> index fb8ac377..0d4ea705 100644
> --- a/src/compress.c
> +++ b/src/compress.c
> @@ -85,6 +85,11 @@ typedef void (*sig_t)(int);
>  #include <zstd_errors.h>
>  #endif
> 
> +#if defined(HAVE_LZLIB_H) && defined(LZLIBSUPPORT)
> +#define BUILTIN_LZLIB
> +#include <lzlib.h>
> +#endif
> +
>  #ifdef DEBUG
>  int tty = -1;
>  #define DPRINTF(...)	do { \
> @@ -180,6 +185,7 @@ private const struct {
>  } compr[] = {
>  #define METH_FROZEN	2
>  #define METH_BZIP	7
> +#define METH_LZIP	8
>  #define METH_XZ		9
>  #define METH_ZSTD	12
>  #define METH_LZMA	13
> @@ -234,6 +240,10 @@ private int uncompressxzlib(const unsigned char
> *, unsigned char **, size_t,
>  private int uncompresszstd(const unsigned char *, unsigned char **, 
> size_t,
>      size_t *);
>  #endif
> +#ifdef BUILTIN_LZLIB
> +private int uncompresslzlib(const unsigned char *, unsigned char **, 
> size_t,
> +    size_t *);
> +#endif
> 
>  static int makeerror(unsigned char **, size_t *, const char *, ...)
>      __attribute__((__format__(__printf__, 3, 4)));
> @@ -754,6 +764,72 @@ err:
>  }
>  #endif
> 
> +#ifdef BUILTIN_LZLIB
> +private int
> +uncompresslzlib(const unsigned char *old, unsigned char **newch,
> +    size_t bytes_max, size_t *n)
> +{
> +	enum LZ_Errno err;
> +	size_t old_remaining = *n;
> +	size_t new_remaining = bytes_max;
> +	size_t total_read = 0;
> +	unsigned char *bufp;
> +	struct LZ_Decoder *dec;
> +
> +	if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
> +		return makeerror(newch, n, "No buffer, %s", strerror(errno));
> +	bufp = *newch;
> +
> +	dec = LZ_decompress_open();
> +	if (!dec) {
> +		free(*newch);
> +		return makeerror(newch, n, "unable to allocate LZ_Decoder");
> +	}
> +	if (LZ_decompress_errno(dec) != LZ_ok)
> +		goto err;
> +
> +	while (1) {
> +		// LZ_decompress_read() stops at member boundaries, so we may
> +		// have more than one successful read after writing all data
> +		// we have.
> +		if (old_remaining > 0) {
> +			int wr = LZ_decompress_write(dec, old, old_remaining);
> +			if (wr < 0)
> +				goto err;
> +			old_remaining -= wr;
> +			old += wr;
> +		}
> +
> +		int rd = LZ_decompress_read(dec, bufp, new_remaining);
> +		if (rd > 0) {
> +			new_remaining -= rd;
> +			bufp += rd;
> +			total_read += rd;
> +		}
> +
> +		if (rd < 0 || LZ_decompress_errno(dec) != LZ_ok)
> +			goto err;
> +		if (new_remaining == 0)
> +			break;
> +		if (old_remaining == 0 && rd == 0)
> +			break;
> +	}
> +
> +	LZ_decompress_close(dec);
> +	*n = total_read;
> +
> +	/* let's keep the nul-terminate tradition */
> +	*bufp = '\0';
> +
> +	return OKDATA;
> +err:
> +	err = LZ_decompress_errno(dec);
> +	LZ_decompress_close(dec);
> +	free(*newch);
> +	return makeerror(newch, n, "lzlib error: %s", LZ_strerror(err));
> +}
> +#endif
> +
> 
>  static int
>  makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
> @@ -924,6 +1000,10 @@ methodname(size_t method)
>  #ifdef BUILTIN_ZSTDLIB
>  	case METH_ZSTD:
>  		return "zstd";
> +#endif
> +#ifdef BUILTIN_LZLIB
> +	case METH_LZIP:
> +		return "lzlib";
>  #endif
>  	default:
>  		return compr[method].argv[0];
> @@ -964,6 +1044,10 @@ uncompressbuf(int fd, size_t bytes_max, size_t
> method, const unsigned char *old,
>  #ifdef BUILTIN_ZSTDLIB
>  	case METH_ZSTD:
>  		return uncompresszstd(old, newch, bytes_max, n);
> +#endif
> +#ifdef BUILTIN_LZLIB
> +	case METH_LZIP:
> +		return uncompresslzlib(old, newch, bytes_max, n);
>  #endif
>  	default:
>  		break;
> --
> 2.37.3

-- 
christos
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: OpenPGP digital signature
URL: <https://mailman.astron.com/pipermail/file/attachments/20220915/91a1abe7/attachment.asc>


More information about the File mailing list