Browse Source

Cherry-pick "Add lzma and bzip built-in decompression support"

Christoph Biedl 4 years ago
parent
commit
81ea71ef01

+ 225 - 0
debian/patches/cherry-pick.FILE5_37-55-gb259a07e.add-lzma-and-bzip-built-in-decompression-support.patch

@@ -0,0 +1,225 @@
+Subject: Add lzma and bzip built-in decompression support
+Origin: FILE5_37-55-gb259a07e <https://github.com/file/file/commit/FILE5_37-55-gb259a07e>
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Thu Jul 18 20:32:06 2019 +0000
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -39,6 +39,16 @@
+ [AS_HELP_STRING([--disable-zlib], [disable zlib compression support @<:@default=auto@:>@])])
+ AC_MSG_RESULT($enable_zlib)
+ 
++AC_MSG_CHECKING(for bzlib support)
++AC_ARG_ENABLE([bzlib],
++[AS_HELP_STRING([--disable-bzlib], [disable bz2lib compression support @<:@default=auto@:>@])])
++AC_MSG_RESULT($enable_bzlib)
++
++AC_MSG_CHECKING(for xzlib support)
++AC_ARG_ENABLE([xzlib],
++[AS_HELP_STRING([--disable-xzlib], [disable liblzma/xz compression support @<:@default=auto@:>@])])
++AC_MSG_RESULT($enable_xzlib)
++
+ AC_MSG_CHECKING(for libseccomp support)
+ AC_ARG_ENABLE([libseccomp],
+ [AS_HELP_STRING([--disable-libseccomp], [disable libseccomp sandboxing @<:@default=auto@:>@])])
+@@ -97,6 +107,12 @@
+ if test "$enable_zlib" != "no"; then
+   AC_CHECK_HEADERS(zlib.h)
+ fi
++if test "$enable_bzlib" != "no"; then
++  AC_CHECK_HEADERS(bzlib.h)
++fi
++if test "$enable_xzlib" != "no"; then
++  AC_CHECK_HEADERS(lzma.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.
+@@ -160,6 +176,12 @@
+ if test "$enable_zlib" != "no"; then
+   AC_CHECK_LIB(z, gzopen)
+ fi
++if test "$enable_bzlib" != "no"; then
++  AC_CHECK_LIB(bz2, BZ2_bzCompressInit)
++fi
++if test "$enable_xzlib" != "no"; then
++  AC_CHECK_LIB(lzma, lzma_stream_decoder)
++fi
+ if test "$enable_libseccomp" != "no"; then
+     AC_CHECK_LIB(seccomp, seccomp_init)
+ fi
+@@ -179,6 +201,22 @@
+ if  test "$ac_cv_header_zlib_h$ac_cv_lib_z_gzopen" = "yesyes"; then
+   AC_DEFINE([ZLIBSUPPORT], 1, [Enable zlib compression support])
+ fi
++if test "$enable_bzlib" = "yes"; then
++  if test "$ac_cv_header_bzlib_h$ac_cv_lib_bz2_BZ2_bzCompressInit" != "yesyes"; then
++    AC_MSG_ERROR([bzlib support requested but not found])
++  fi
++fi
++if  test "$ac_cv_header_bzlib_h$ac_cv_lib_bz2_BZ2_bzCompressInit" = "yesyes"; then
++  AC_DEFINE([BZLIBSUPPORT], 1, [Enable bzlib compression support])
++fi
++if test "$enable_xzlib" = "yes"; then
++  if test "$ac_cv_header_lzma_h$ac_cv_lib_lzma_lzma_stream_decoder" != "yesyes"; then
++    AC_MSG_ERROR([xzlib support requested but not found])
++  fi
++fi
++if  test "$ac_cv_header_lzma_h$ac_cv_lib_lzma_lzma_stream_decoder" = "yesyes"; then
++  AC_DEFINE([XZLIBSUPPORT], 1, [Enable xzlib compression support])
++fi
+ 
+ AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile])
+ AC_OUTPUT
+--- a/src/compress.c
++++ b/src/compress.c
+@@ -66,11 +66,16 @@
+ #include <zlib.h>
+ #endif
+ 
+-#if defined(HAVE_BZLIB_H)
++#if defined(HAVE_BZLIB_H) || defined(BZLIBSUPPORT)
+ #define BUILTIN_BZLIB
+ #include <bzlib.h>
+ #endif
+ 
++#if defined(HAVE_XZLIB_H) || defined(XZLIBSUPPORT)
++#define BUILTIN_XZLIB
++#include <lzma.h>
++#endif
++
+ #ifdef DEBUG
+ int tty = -1;
+ #define DPRINTF(...)	do { \
+@@ -190,7 +195,11 @@
+ #endif
+ #ifdef BUILTIN_BZLIB
+ private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
+-    size_t *, int);
++    size_t *);
++#endif
++#ifdef BUILTIN_XZLIB
++private int uncompressxzlib(const unsigned char *, unsigned char **, size_t,
++    size_t *);
+ #endif
+ 
+ static int makeerror(unsigned char **, size_t *, const char *, ...)
+@@ -570,6 +579,90 @@
+ }
+ #endif
+ 
++#ifdef BUILTIN_BZLIB
++private int
++uncompressbzlib(const unsigned char *old, unsigned char **newch,
++    size_t bytes_max, size_t *n)
++{
++	int rc;
++	bz_stream bz;
++
++	memset(&bz, 0, sizeof(bz));
++	rc = BZ2_bzDecompressInit(&bz, 0, 0);
++	if (rc != BZ_OK)
++		goto err;
++
++	if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
++		return makeerror(newch, n, "No buffer, %s", strerror(errno));
++
++	bz.next_in = CCAST(char *, RCAST(const char *, old));
++	bz.avail_in = CAST(uint32_t, *n);
++	bz.next_out = RCAST(char *, *newch);
++	bz.avail_out = CAST(unsigned int, bytes_max);
++
++	rc = BZ2_bzDecompress(&bz);
++	if (rc != BZ_OK && rc != BZ_STREAM_END)
++		goto err;
++
++	/* Assume byte_max is within 32bit */
++	/* assert(bz.total_out_hi32 == 0); */
++	*n = CAST(size_t, bz.total_out_lo32);
++	rc = BZ2_bzDecompressEnd(&bz);
++	if (rc != BZ_OK)
++		goto err;
++
++	/* let's keep the nul-terminate tradition */
++	(*newch)[*n] = '\0';
++
++	return OKDATA;
++err:
++	snprintf(RCAST(char *, *newch), bytes_max, "bunzip error %d", rc);
++	*n = strlen(RCAST(char *, *newch));
++	return ERRDATA;
++}
++#endif
++
++#ifdef BUILTIN_XZLIB
++private int
++uncompressxzlib(const unsigned char *old, unsigned char **newch,
++    size_t bytes_max, size_t *n)
++{
++	int rc;
++	lzma_stream xz;
++
++	memset(&xz, 0, sizeof(xz));
++	rc = lzma_auto_decoder(&xz, UINT64_MAX, 0);
++	if (rc != LZMA_OK)
++		goto err;
++
++	if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
++		return makeerror(newch, n, "No buffer, %s", strerror(errno));
++
++	xz.next_in = CCAST(const uint8_t *, old);
++	xz.avail_in = CAST(uint32_t, *n);
++	xz.next_out = RCAST(uint8_t *, *newch);
++	xz.avail_out = CAST(unsigned int, bytes_max);
++
++	rc = lzma_code(&xz, LZMA_RUN);
++	if (rc != LZMA_OK && rc != LZMA_STREAM_END)
++		goto err;
++
++	*n = CAST(size_t, xz.total_out);
++
++	lzma_end(&xz);
++
++	/* let's keep the nul-terminate tradition */
++	(*newch)[*n] = '\0';
++
++	return OKDATA;
++err:
++	snprintf(RCAST(char *, *newch), bytes_max, "unxz error %d", rc);
++	*n = strlen(RCAST(char *, *newch));
++	return ERRDATA;
++}
++#endif
++
++
+ static int
+ makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
+ {
+@@ -702,6 +795,15 @@
+ 	if (compr[method].maglen == 0)
+ 		return uncompresszlib(old, newch, bytes_max, n, 1);
+ #endif
++#ifdef BUILTIN_BZLIB
++	if (method == 7)
++		return uncompressbzlib(old, newch, bytes_max, n);
++#endif
++#ifdef BUILTIN_XZLIB
++	if (method == 9 || method == 13)
++		return uncompressxzlib(old, newch, bytes_max, n);
++#endif
++
+ 	(void)fflush(stdout);
+ 	(void)fflush(stderr);
+ 
+--- a/src/seccomp.c
++++ b/src/seccomp.c
+@@ -167,6 +167,9 @@
+  	ALLOW_RULE(fcntl64);
+ 	ALLOW_RULE(fstat);
+  	ALLOW_RULE(fstat64);
++#ifdef XZLIBSUPPORT
++	ALLOW_RULE(futex);
++#endif
+ 	ALLOW_RULE(getdents);
+ #ifdef __NR_getdents64
+ 	ALLOW_RULE(getdents64);

+ 1 - 0
debian/patches/series

@@ -2,6 +2,7 @@
 cherry-pick.FILE5_37-47-g62de35af.disable-gem-gdos-fonts-for-now-needs-to-be-stronger.patch
 cherry-pick.FILE5_37-46-g103c6ec2.dont-print-the-string-entry-unless-the-zip-entry-matched-christoph-biedl.patch
 cherry-pick.FILE5_37-54-g119cc185.add-lzma-decompression-support.patch
+cherry-pick.FILE5_37-55-gb259a07e.add-lzma-and-bzip-built-in-decompression-support.patch
 
 # patches that should go upstream