Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Sep 2017 23:33:19 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r324145 - in vendor/libarchive/dist: . build/cmake build/pkgconfig cat/test contrib/android cpio cpio/test libarchive libarchive/test tar tar/test test_utils
Message-ID:  <201709302333.v8UNXJLc011212@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Sat Sep 30 23:33:19 2017
New Revision: 324145
URL: https://svnweb.freebsd.org/changeset/base/324145

Log:
  Update vendor/libarchive to git 92366744a52f3fa83c3899e375e415a5080a05f2
  
  Relevant vendor changes:
    PR #905: Support for Zstandard read and write filters
    PR #922: Avoid overflow when reading corrupt cpio archive
    Issue #935: heap-based buffer overflow in xml_data (CVE-2017-14166)
    OSS-Fuzz 2936: Place a limit on the mtree line length
    OSS-Fuzz 2394: Ensure that the ZIP AES extension header is large enough
    OSS-Fuzz 573: Read off-by-one error in RAR archives (CVE-2017-14502)
  
  Security: CVE-2017-14166, CVE-2017-14502

Added:
  vendor/libarchive/dist/cat/test/test_empty.zst.uu
  vendor/libarchive/dist/cat/test/test_empty_zstd.c   (contents, props changed)
  vendor/libarchive/dist/cat/test/test_expand.zst.uu
  vendor/libarchive/dist/cat/test/test_expand_zstd.c   (contents, props changed)
  vendor/libarchive/dist/cpio/test/test_extract.cpio.zst.uu
  vendor/libarchive/dist/cpio/test/test_extract_cpio_zstd.c   (contents, props changed)
  vendor/libarchive/dist/cpio/test/test_option_zstd.c   (contents, props changed)
  vendor/libarchive/dist/libarchive/archive_read_support_filter_zstd.c   (contents, props changed)
  vendor/libarchive/dist/libarchive/archive_write_add_filter_zstd.c   (contents, props changed)
  vendor/libarchive/dist/libarchive/test/test_compat_zstd.c   (contents, props changed)
  vendor/libarchive/dist/libarchive/test/test_compat_zstd_1.tar.zst.uu
  vendor/libarchive/dist/libarchive/test/test_write_filter_zstd.c   (contents, props changed)
  vendor/libarchive/dist/tar/test/test_extract.tar.zst.uu
  vendor/libarchive/dist/tar/test/test_extract_tar_zstd.c   (contents, props changed)
  vendor/libarchive/dist/tar/test/test_option_zstd.c   (contents, props changed)
Modified:
  vendor/libarchive/dist/.travis.yml
  vendor/libarchive/dist/CMakeLists.txt
  vendor/libarchive/dist/Makefile.am
  vendor/libarchive/dist/build/cmake/config.h.in
  vendor/libarchive/dist/build/pkgconfig/libarchive.pc.in
  vendor/libarchive/dist/cat/test/CMakeLists.txt
  vendor/libarchive/dist/configure.ac
  vendor/libarchive/dist/contrib/android/Android.mk
  vendor/libarchive/dist/cpio/bsdcpio.1
  vendor/libarchive/dist/cpio/cmdline.c
  vendor/libarchive/dist/cpio/cpio.c
  vendor/libarchive/dist/cpio/cpio.h
  vendor/libarchive/dist/cpio/test/CMakeLists.txt
  vendor/libarchive/dist/libarchive/CMakeLists.txt
  vendor/libarchive/dist/libarchive/archive.h
  vendor/libarchive/dist/libarchive/archive_cmdline.c
  vendor/libarchive/dist/libarchive/archive_platform.h
  vendor/libarchive/dist/libarchive/archive_read_append_filter.c
  vendor/libarchive/dist/libarchive/archive_read_disk_entry_from_file.c
  vendor/libarchive/dist/libarchive/archive_read_filter.3
  vendor/libarchive/dist/libarchive/archive_read_support_filter_all.c
  vendor/libarchive/dist/libarchive/archive_read_support_format_cpio.c
  vendor/libarchive/dist/libarchive/archive_read_support_format_mtree.c
  vendor/libarchive/dist/libarchive/archive_read_support_format_rar.c
  vendor/libarchive/dist/libarchive/archive_read_support_format_tar.c
  vendor/libarchive/dist/libarchive/archive_read_support_format_xar.c
  vendor/libarchive/dist/libarchive/archive_read_support_format_zip.c
  vendor/libarchive/dist/libarchive/archive_string.c
  vendor/libarchive/dist/libarchive/archive_version_details.c
  vendor/libarchive/dist/libarchive/archive_write.3
  vendor/libarchive/dist/libarchive/archive_write_add_filter.c
  vendor/libarchive/dist/libarchive/archive_write_add_filter_by_name.c
  vendor/libarchive/dist/libarchive/archive_write_filter.3
  vendor/libarchive/dist/libarchive/archive_write_set_format_pax.c
  vendor/libarchive/dist/libarchive/test/CMakeLists.txt
  vendor/libarchive/dist/libarchive/test/test_archive_write_add_filter_by_name.c
  vendor/libarchive/dist/libarchive/test/test_fuzz.c
  vendor/libarchive/dist/tar/bsdtar.1
  vendor/libarchive/dist/tar/bsdtar.c
  vendor/libarchive/dist/tar/bsdtar.h
  vendor/libarchive/dist/tar/cmdline.c
  vendor/libarchive/dist/tar/creation_set.c
  vendor/libarchive/dist/tar/test/CMakeLists.txt
  vendor/libarchive/dist/tar/test/test_option_acls.c
  vendor/libarchive/dist/test_utils/test_common.h
  vendor/libarchive/dist/test_utils/test_main.c

Modified: vendor/libarchive/dist/.travis.yml
==============================================================================
--- vendor/libarchive/dist/.travis.yml	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/.travis.yml	Sat Sep 30 23:33:19 2017	(r324145)
@@ -25,6 +25,6 @@ matrix:
 before_install:
   - if [ `uname` = "Darwin" ]; then brew update; fi
 install:
-  - if [ `uname` = "Darwin" ]; then brew install xz lzop lz4; fi
+  - if [ `uname` = "Darwin" ]; then brew install xz lzop lz4 zstd; fi
 script:
   - build/ci_build.sh

Modified: vendor/libarchive/dist/CMakeLists.txt
==============================================================================
--- vendor/libarchive/dist/CMakeLists.txt	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/CMakeLists.txt	Sat Sep 30 23:33:19 2017	(r324145)
@@ -533,6 +533,31 @@ IF(LZ4_FOUND)
 ENDIF(LZ4_FOUND)
 MARK_AS_ADVANCED(CLEAR LZ4_INCLUDE_DIR)
 MARK_AS_ADVANCED(CLEAR LZ4_LIBRARY)
+#
+# Find Zstd
+#
+IF (ZSTD_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(ZSTD_FIND_QUIETLY TRUE)
+ENDIF (ZSTD_INCLUDE_DIR)
+
+FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
+FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
+IF(ZSTD_FOUND)
+  SET(HAVE_ZSTD_H 1)
+  INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR})
+  LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY})
+  SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY})
+  SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR})
+  CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD)
+  #
+  # TODO: test for static library.
+  #
+ENDIF(ZSTD_FOUND)
+MARK_AS_ADVANCED(CLEAR ZSTD_INCLUDE_DIR)
+MARK_AS_ADVANCED(CLEAR ZSTD_LIBRARY)
 
 #
 # Check headers

Modified: vendor/libarchive/dist/Makefile.am
==============================================================================
--- vendor/libarchive/dist/Makefile.am	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/Makefile.am	Sat Sep 30 23:33:19 2017	(r324145)
@@ -167,6 +167,7 @@ libarchive_la_SOURCES= \
 	libarchive/archive_read_support_filter_rpm.c \
 	libarchive/archive_read_support_filter_uu.c \
 	libarchive/archive_read_support_filter_xz.c \
+	libarchive/archive_read_support_filter_zstd.c \
 	libarchive/archive_read_support_format_7zip.c \
 	libarchive/archive_read_support_format_all.c \
 	libarchive/archive_read_support_format_ar.c \
@@ -213,6 +214,7 @@ libarchive_la_SOURCES= \
 	libarchive/archive_write_add_filter_program.c \
 	libarchive/archive_write_add_filter_uuencode.c \
 	libarchive/archive_write_add_filter_xz.c \
+	libarchive/archive_write_add_filter_zstd.c \
 	libarchive/archive_write_set_format.c \
 	libarchive/archive_write_set_format_7zip.c \
 	libarchive/archive_write_set_format_ar.c \
@@ -402,6 +404,7 @@ libarchive_test_SOURCES= \
 	libarchive/test/test_compat_uudecode_large.c \
 	libarchive/test/test_compat_xz.c \
 	libarchive/test/test_compat_zip.c \
+	libarchive/test/test_compat_zstd.c \
 	libarchive/test/test_empty_write.c \
 	libarchive/test/test_entry.c \
 	libarchive/test/test_entry_strmode.c \
@@ -559,6 +562,7 @@ libarchive_test_SOURCES= \
 	libarchive/test/test_write_filter_program.c \
 	libarchive/test/test_write_filter_uuencode.c \
 	libarchive/test/test_write_filter_xz.c \
+	libarchive/test/test_write_filter_zstd.c \
 	libarchive/test/test_write_format_7zip.c \
 	libarchive/test/test_write_format_7zip_empty.c \
 	libarchive/test/test_write_format_7zip_large.c \
@@ -677,6 +681,7 @@ libarchive_test_EXTRA_DIST=\
 	libarchive/test/test_compat_zip_5.zip.uu \
 	libarchive/test/test_compat_zip_6.zip.uu \
 	libarchive/test/test_compat_zip_7.xps.uu \
+	libarchive/test/test_compat_zstd_1.tar.zst.uu \
 	libarchive/test/test_fuzz.cab.uu \
 	libarchive/test/test_fuzz.lzh.uu \
 	libarchive/test/test_fuzz_1.iso.Z.uu \
@@ -961,6 +966,7 @@ bsdtar_test_SOURCES= \
 	tar/test/test_extract_tar_lzma.c \
 	tar/test/test_extract_tar_lzo.c \
 	tar/test/test_extract_tar_xz.c \
+	tar/test/test_extract_tar_zstd.c \
 	tar/test/test_format_newc.c \
 	tar/test/test_help.c \
 	tar/test/test_leading_slash.c \
@@ -1000,6 +1006,7 @@ bsdtar_test_SOURCES= \
 	tar/test/test_option_xattrs.c \
 	tar/test/test_option_xz.c \
 	tar/test/test_option_z.c \
+	tar/test/test_option_zstd.c \
 	tar/test/test_patterns.c \
 	tar/test/test_print_longpath.c \
 	tar/test/test_stdio.c \
@@ -1036,6 +1043,7 @@ bsdtar_test_EXTRA_DIST= \
 	tar/test/test_extract.tar.lrz.uu \
 	tar/test/test_extract.tar.lz.uu \
 	tar/test/test_extract.tar.lz4.uu \
+	tar/test/test_extract.tar.zst.uu \
 	tar/test/test_extract.tar.lzma.uu \
 	tar/test/test_extract.tar.lzo.uu \
 	tar/test/test_extract.tar.xz.uu \
@@ -1121,6 +1129,7 @@ bsdcpio_test_SOURCES= \
 	cpio/test/test_extract_cpio_lzma.c \
 	cpio/test/test_extract_cpio_lzo.c \
 	cpio/test/test_extract_cpio_xz.c \
+	cpio/test/test_extract_cpio_zstd.c \
 	cpio/test/test_format_newc.c \
 	cpio/test/test_gcpio_compat.c \
 	cpio/test/test_missing_file.c \
@@ -1151,6 +1160,7 @@ bsdcpio_test_SOURCES= \
 	cpio/test/test_option_xz.c \
 	cpio/test/test_option_y.c \
 	cpio/test/test_option_z.c \
+	cpio/test/test_option_zstd.c \
 	cpio/test/test_owner_parse.c \
 	cpio/test/test_passthrough_dotdot.c \
 	cpio/test/test_passthrough_reverse.c
@@ -1184,6 +1194,7 @@ bsdcpio_test_EXTRA_DIST= \
 	cpio/test/test_extract.cpio.lrz.uu \
 	cpio/test/test_extract.cpio.lz.uu \
 	cpio/test/test_extract.cpio.lz4.uu \
+	cpio/test/test_extract.cpio.zst.uu \
 	cpio/test/test_extract.cpio.lzma.uu \
 	cpio/test/test_extract.cpio.lzo.uu \
 	cpio/test/test_extract.cpio.xz.uu \
@@ -1259,6 +1270,7 @@ bsdcat_test_SOURCES= \
 	cat/test/test_empty_gz.c \
 	cat/test/test_empty_lz4.c \
 	cat/test/test_empty_xz.c \
+	cat/test/test_empty_zstd.c \
 	cat/test/test_error.c \
 	cat/test/test_error_mixed.c \
 	cat/test/test_expand_Z.c \
@@ -1268,6 +1280,7 @@ bsdcat_test_SOURCES= \
 	cat/test/test_expand_mixed.c \
 	cat/test/test_expand_plain.c \
 	cat/test/test_expand_xz.c \
+	cat/test/test_expand_zstd.c \
 	cat/test/test_help.c \
 	cat/test/test_version.c
 
@@ -1294,11 +1307,13 @@ bsdcat_test_EXTRA_DIST= \
 	cat/test/list.h \
 	cat/test/test_empty.gz.uu \
 	cat/test/test_empty.lz4.uu \
+	cat/test/test_empty.zst.uu \
 	cat/test/test_empty.xz.uu \
 	cat/test/test_expand.Z.uu \
 	cat/test/test_expand.bz2.uu \
 	cat/test/test_expand.gz.uu \
 	cat/test/test_expand.lz4.uu \
+	cat/test/test_expand.zst.uu \
 	cat/test/test_expand.plain.uu \
 	cat/test/test_expand.xz.uu \
 	cat/test/CMakeLists.txt

Modified: vendor/libarchive/dist/build/cmake/config.h.in
==============================================================================
--- vendor/libarchive/dist/build/cmake/config.h.in	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/build/cmake/config.h.in	Sat Sep 30 23:33:19 2017	(r324145)
@@ -725,6 +725,9 @@ typedef uint64_t uintmax_t;
 /* Define to 1 if you have the `z' library (-lz). */
 #cmakedefine HAVE_LIBZ 1
 
+/* Define to 1 if you have the `zstd' library (-lzstd). */
+#cmakedefine HAVE_LIBZSTD 1
+
 /* Define to 1 if you have the <limits.h> header file. */
 #cmakedefine HAVE_LIMITS_H 1
 
@@ -1178,6 +1181,9 @@ typedef uint64_t uintmax_t;
 
 /* Define to 1 if you have the <zlib.h> header file. */
 #cmakedefine HAVE_ZLIB_H 1
+
+/* Define to 1 if you have the <zstd.h> header file. */
+#cmakedefine HAVE_ZSTD_H 1
 
 /* Define to 1 if you have the `_ctime64_s' function. */
 #cmakedefine HAVE__CTIME64_S 1

Modified: vendor/libarchive/dist/build/pkgconfig/libarchive.pc.in
==============================================================================
--- vendor/libarchive/dist/build/pkgconfig/libarchive.pc.in	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/build/pkgconfig/libarchive.pc.in	Sat Sep 30 23:33:19 2017	(r324145)
@@ -7,5 +7,6 @@ Name: libarchive
 Description: library that can create and read several streaming archive formats
 Version: @VERSION@
 Cflags: -I${includedir}
+Cflags.private: -DLIBARCHIVE_STATIC
 Libs: -L${libdir} -larchive
 Libs.private: @LIBS@

Modified: vendor/libarchive/dist/cat/test/CMakeLists.txt
==============================================================================
--- vendor/libarchive/dist/cat/test/CMakeLists.txt	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/cat/test/CMakeLists.txt	Sat Sep 30 23:33:19 2017	(r324145)
@@ -12,6 +12,7 @@ IF(ENABLE_CAT AND ENABLE_TEST)
     test_empty_gz.c
     test_empty_lz4.c
     test_empty_xz.c
+    test_empty_zstd.c
     test_error.c
     test_error_mixed.c
     test_expand_Z.c
@@ -21,6 +22,7 @@ IF(ENABLE_CAT AND ENABLE_TEST)
     test_expand_mixed.c
     test_expand_plain.c
     test_expand_xz.c
+    test_expand_zstd.c
     test_help.c
     test_version.c
   )

Added: vendor/libarchive/dist/cat/test/test_empty.zst.uu
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libarchive/dist/cat/test/test_empty.zst.uu	Sat Sep 30 23:33:19 2017	(r324145)
@@ -0,0 +1,4 @@
+begin 644 test_empty.zst
+-*+4O_010`0``F>G840``
+`
+end

Added: vendor/libarchive/dist/cat/test/test_empty_zstd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libarchive/dist/cat/test/test_empty_zstd.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2017 Sean Purcell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_empty_zstd)
+{
+	const char *reffile = "test_empty.zst";
+	int f;
+
+	extract_reference_file(reffile);
+	f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
+	if (f == 0 || canZstd()) {
+		assertEqualInt(0, f);
+		assertEmptyFile("test.out");
+		assertEmptyFile("test.err");
+	} else {
+		skipping("It seems zstd is not supported on this platform");
+	}
+}

Added: vendor/libarchive/dist/cat/test/test_expand.zst.uu
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libarchive/dist/cat/test/test_expand.zst.uu	Sat Sep 30 23:33:19 2017	(r324145)
@@ -0,0 +1,4 @@
+begin 644 test_expand.zst
+J*+4O_010Z0``8V]N=&5N=',@;V8@=&5S=%]E>'!A;F0N>G-T+@J;23#F
+`
+end

Added: vendor/libarchive/dist/cat/test/test_expand_zstd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libarchive/dist/cat/test/test_expand_zstd.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2017 Sean Purcell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_expand_zstd)
+{
+	const char *reffile = "test_expand.zst";
+	int f;
+
+	extract_reference_file(reffile);
+	f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
+	if (f == 0 || canZstd()) {
+		assertEqualInt(0, f);
+		assertTextFileContents("contents of test_expand.zst.\n", "test.out");
+		assertEmptyFile("test.err");
+	} else {
+		skipping("It seems zstd is not supported on this platform");
+	}
+}

Modified: vendor/libarchive/dist/configure.ac
==============================================================================
--- vendor/libarchive/dist/configure.ac	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/configure.ac	Sat Sep 30 23:33:19 2017	(r324145)
@@ -367,6 +367,14 @@ if test "x$with_lz4" != "xno"; then
   AC_CHECK_LIB(lz4,LZ4_decompress_safe)
 fi
 
+AC_ARG_WITH([zstd],
+  AS_HELP_STRING([--without-zstd], [Don't build support for zstd through libzstd]))
+
+if test "x$with_zstd" != "xno"; then
+  AC_CHECK_HEADERS([zstd.h])
+  AC_CHECK_LIB(zstd,ZSTD_compressStream)
+fi
+
 AC_ARG_WITH([lzma],
   AS_HELP_STRING([--without-lzma], [Don't build support for xz through lzma]))
 
@@ -682,7 +690,7 @@ AC_ARG_ENABLE([xattr],
 		[Disable Extended Attributes support (default: check)]))
 
 if test "x$enable_xattr" != "xno"; then
-    AC_SEARCH_LIBS([setxattr], [attr])
+    AC_SEARCH_LIBS([setxattr], [attr gnu])
     AC_CHECK_DECLS([EXTATTR_NAMESPACE_USER], [], [], [#include <sys/types.h>
 #include <sys/extattr.h>
 ])

Modified: vendor/libarchive/dist/contrib/android/Android.mk
==============================================================================
--- vendor/libarchive/dist/contrib/android/Android.mk	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/contrib/android/Android.mk	Sat Sep 30 23:33:19 2017	(r324145)
@@ -74,6 +74,7 @@ libarchive_src_files := libarchive/archive_acl.c \
 						libarchive/archive_read_support_filter_rpm.c \
 						libarchive/archive_read_support_filter_uu.c \
 						libarchive/archive_read_support_filter_xz.c \
+						libarchive/archive_read_support_filter_zstd.c \
 						libarchive/archive_read_support_format_7zip.c \
 						libarchive/archive_read_support_format_all.c \
 						libarchive/archive_read_support_format_ar.c \
@@ -116,6 +117,7 @@ libarchive_src_files := libarchive/archive_acl.c \
 						libarchive/archive_write_add_filter_program.c \
 						libarchive/archive_write_add_filter_uuencode.c \
 						libarchive/archive_write_add_filter_xz.c \
+						libarchive/archive_write_add_filter_zstd.c \
 						libarchive/archive_write_set_format.c \
 						libarchive/archive_write_set_format_7zip.c \
 						libarchive/archive_write_set_format_ar.c \

Modified: vendor/libarchive/dist/cpio/bsdcpio.1
==============================================================================
--- vendor/libarchive/dist/cpio/bsdcpio.1	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/cpio/bsdcpio.1	Sat Sep 30 23:33:19 2017	(r324145)
@@ -187,6 +187,11 @@ In input mode, this option is ignored.
 Compress the archive with lz4-compatible compression before writing it.
 In input mode, this option is ignored; lz4 compression is recognized
 automatically on input.
+.It Fl Fl zstd
+(o mode only)
+Compress the archive with zstd-compatible compression before writing it.
+In input mode, this option is ignored; zstd compression is recognized
+automatically on input.
 .It Fl Fl lzma
 (o mode only)
 Compress the file with lzma-compatible compression before writing it.

Modified: vendor/libarchive/dist/cpio/cmdline.c
==============================================================================
--- vendor/libarchive/dist/cpio/cmdline.c	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/cpio/cmdline.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -92,6 +92,7 @@ static const struct option {
 	{ "verbose",			0, 'v' },
 	{ "version",			0, OPTION_VERSION },
 	{ "xz",				0, 'J' },
+	{ "zstd",			0, OPTION_ZSTD },
 	{ NULL, 0, 0 }
 };
 

Modified: vendor/libarchive/dist/cpio/cpio.c
==============================================================================
--- vendor/libarchive/dist/cpio/cpio.c	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/cpio/cpio.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -269,6 +269,7 @@ main(int argc, char *argv[])
 		case OPTION_LZ4:
 		case OPTION_LZMA: /* GNU tar, others */
 		case OPTION_LZOP: /* GNU tar, others */
+		case OPTION_ZSTD:
 			cpio->compress = opt;
 			break;
 		case 'm': /* POSIX 1997 */
@@ -545,6 +546,9 @@ mode_out(struct cpio *cpio)
 		break;
 	case OPTION_LZOP:
 		r = archive_write_add_filter_lzop(cpio->archive);
+		break;
+	case OPTION_ZSTD:
+		r = archive_write_add_filter_zstd(cpio->archive);
 		break;
 	case 'j': case 'y':
 		r = archive_write_add_filter_bzip2(cpio->archive);

Modified: vendor/libarchive/dist/cpio/cpio.h
==============================================================================
--- vendor/libarchive/dist/cpio/cpio.h	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/cpio/cpio.h	Sat Sep 30 23:33:19 2017	(r324145)
@@ -111,7 +111,8 @@ enum {
 	OPTION_PRESERVE_OWNER,
 	OPTION_QUIET,
 	OPTION_UUENCODE,
-	OPTION_VERSION
+	OPTION_VERSION,
+	OPTION_ZSTD,
 };
 
 int	cpio_getopt(struct cpio *cpio);

Modified: vendor/libarchive/dist/cpio/test/CMakeLists.txt
==============================================================================
--- vendor/libarchive/dist/cpio/test/CMakeLists.txt	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/cpio/test/CMakeLists.txt	Sat Sep 30 23:33:19 2017	(r324145)
@@ -23,6 +23,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
     test_extract_cpio_lzma
     test_extract_cpio_lzo
     test_extract_cpio_xz
+    test_extract_cpio_zstd
     test_format_newc.c
     test_gcpio_compat.c
     test_missing_file.c
@@ -53,6 +54,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
     test_option_xz.c
     test_option_y.c
     test_option_z.c
+    test_option_zstd.c
     test_owner_parse.c
     test_passthrough_dotdot.c
     test_passthrough_reverse.c

Added: vendor/libarchive/dist/cpio/test/test_extract.cpio.zst.uu
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libarchive/dist/cpio/test/test_extract.cpio.zst.uu	Sat Sep 30 23:33:19 2017	(r324145)
@@ -0,0 +1,6 @@
+begin 644 test_extract.cpio.zst
+M*+4O_01090,`,@41%X")&@#'G6T\K16_MR)#=DK)5:.1,2J0HY2"!(1!`!7R
+M$(UB`2"*D41;J2UF&)<0!Y7X'TU<%W.\W^R]GO-WW^OO^QX0`%P<]30-!#U`
+?!KD!`#XP,_`U4`HT3+RF:#!7Y\V@R)5"7P"^;WEUK@``
+`
+end

Added: vendor/libarchive/dist/cpio/test/test_extract_cpio_zstd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libarchive/dist/cpio/test/test_extract_cpio_zstd.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2017 Sean Purcell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_extract_cpio_zstd)
+{
+	const char *reffile = "test_extract.cpio.zst";
+	int f;
+
+	extract_reference_file(reffile);
+	f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
+	if (f == 0 || canZstd()) {
+		assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
+		    testprog, reffile));
+
+		assertFileExists("file1");
+		assertTextFileContents("contents of file1.\n", "file1");
+		assertFileExists("file2");
+		assertTextFileContents("contents of file2.\n", "file2");
+		assertEmptyFile("test.out");
+		assertTextFileContents("1 block\n", "test.err");
+	} else {
+		skipping("It seems zstd is not supported on this platform");
+	}
+}

Added: vendor/libarchive/dist/cpio/test/test_option_zstd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libarchive/dist/cpio/test/test_option_zstd.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2017 Sean Purcell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_zstd)
+{
+	char *p;
+	int r;
+	size_t s;
+
+	/* Create a file. */
+	assertMakeFile("f", 0644, "a");
+
+	/* Archive it with zstd compression. */
+	r = systemf("echo f | %s -o --zstd >archive.out 2>archive.err",
+	    testprog);
+	p = slurpfile(&s, "archive.err");
+	p[s] = '\0';
+	if (r != 0) {
+		if (strstr(p, "Unsupported compression") != NULL) {
+			skipping("This version of bsdcpio was compiled "
+			    "without zstd support");
+			goto done;
+		}
+		/* POSIX permits different handling of the spawnp
+		 * system call used to launch the subsidiary
+		 * program: */
+		/* Some systems fail immediately to spawn the new process. */
+		if (strstr(p, "Can't launch") != NULL && !canZstd()) {
+			skipping("This version of bsdcpio uses an external zstd program "
+			    "but no such program is available on this system.");
+			goto done;
+		}
+		/* Some systems successfully spawn the new process,
+		 * but fail to exec a program within that process.
+		 * This results in failure at the first attempt to
+		 * write. */
+		if (strstr(p, "Can't write") != NULL && !canZstd()) {
+			skipping("This version of bsdcpio uses an external zstd program "
+			    "but no such program is available on this system.");
+			goto done;
+		}
+		/* On some systems the error won't be detected until closing
+		   time, by a 127 exit error returned by waitpid. */
+		if (strstr(p, "Error closing") != NULL && !canZstd()) {
+			skipping("This version of bsdcpio uses an external zstd program "
+			    "but no such program is available on this system.");
+			return;
+		}
+		failure("--zstd option is broken: %s", p);
+		assertEqualInt(r, 0);
+		goto done;
+	}
+	free(p);
+	/* Check that the archive file has an zstd signature. */
+	p = slurpfile(&s, "archive.out");
+	assert(s > 2);
+	assertEqualMem(p, "\x28\xb5\x2f\xfd", 4);
+
+done:
+	free(p);
+}

Modified: vendor/libarchive/dist/libarchive/CMakeLists.txt
==============================================================================
--- vendor/libarchive/dist/libarchive/CMakeLists.txt	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/libarchive/CMakeLists.txt	Sat Sep 30 23:33:19 2017	(r324145)
@@ -88,6 +88,7 @@ SET(libarchive_SOURCES
   archive_read_support_filter_rpm.c
   archive_read_support_filter_uu.c
   archive_read_support_filter_xz.c
+  archive_read_support_filter_zstd.c
   archive_read_support_format_7zip.c
   archive_read_support_format_all.c
   archive_read_support_format_ar.c
@@ -134,6 +135,7 @@ SET(libarchive_SOURCES
   archive_write_add_filter_program.c
   archive_write_add_filter_uuencode.c
   archive_write_add_filter_xz.c
+  archive_write_add_filter_zstd.c
   archive_write_set_format.c
   archive_write_set_format_7zip.c
   archive_write_set_format_ar.c

Modified: vendor/libarchive/dist/libarchive/archive.h
==============================================================================
--- vendor/libarchive/dist/libarchive/archive.h	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/libarchive/archive.h	Sat Sep 30 23:33:19 2017	(r324145)
@@ -177,6 +177,7 @@ __LA_DECL const char *  archive_zlib_version(void);
 __LA_DECL const char *  archive_liblzma_version(void);
 __LA_DECL const char *  archive_bzlib_version(void);
 __LA_DECL const char *  archive_liblz4_version(void);
+__LA_DECL const char *  archive_libzstd_version(void);
 
 /* Declare our basic types. */
 struct archive;
@@ -276,6 +277,7 @@ typedef const char *archive_passphrase_callback(struct
 #define	ARCHIVE_FILTER_LZOP	11
 #define	ARCHIVE_FILTER_GRZIP	12
 #define	ARCHIVE_FILTER_LZ4	13
+#define	ARCHIVE_FILTER_ZSTD	14
 
 #if ARCHIVE_VERSION_NUMBER < 4000000
 #define	ARCHIVE_COMPRESSION_NONE	ARCHIVE_FILTER_NONE
@@ -433,6 +435,7 @@ __LA_DECL int archive_read_support_filter_program_sign
 __LA_DECL int archive_read_support_filter_rpm(struct archive *);
 __LA_DECL int archive_read_support_filter_uu(struct archive *);
 __LA_DECL int archive_read_support_filter_xz(struct archive *);
+__LA_DECL int archive_read_support_filter_zstd(struct archive *);
 
 __LA_DECL int archive_read_support_format_7zip(struct archive *);
 __LA_DECL int archive_read_support_format_all(struct archive *);
@@ -778,6 +781,7 @@ __LA_DECL int archive_write_add_filter_program(struct 
 		     const char *cmd);
 __LA_DECL int archive_write_add_filter_uuencode(struct archive *);
 __LA_DECL int archive_write_add_filter_xz(struct archive *);
+__LA_DECL int archive_write_add_filter_zstd(struct archive *);
 
 
 /* A convenience function to set the format based on the code or name. */

Modified: vendor/libarchive/dist/libarchive/archive_cmdline.c
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_cmdline.c	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/libarchive/archive_cmdline.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -100,10 +100,10 @@ get_argument(struct archive_string *as, const char *p)
 
 /*
  * Set up command line arguments.
- * Returns ARChIVE_OK if everything okey.
- * Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an
+ * Returns ARCHIVE_OK if everything okey.
+ * Returns ARCHIVE_FAILED if there is a lack of the `"' terminator or an
  * empty command line.
- * Returns ARChIVE_FATAL if no memory.
+ * Returns ARCHIVE_FATAL if no memory.
  */
 int
 __archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)

Modified: vendor/libarchive/dist/libarchive/archive_platform.h
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_platform.h	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/libarchive/archive_platform.h	Sat Sep 30 23:33:19 2017	(r324145)
@@ -52,6 +52,17 @@
 #error Oops: No config.h and no pre-built configuration in archive_platform.h.
 #endif
 
+/* On macOS check for some symbols based on the deployment target version.  */
+#if defined(__APPLE__)
+# undef HAVE_FUTIMENS
+# undef HAVE_UTIMENSAT
+# include <AvailabilityMacros.h>
+# if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+#  define HAVE_FUTIMENS 1
+#  define HAVE_UTIMENSAT 1
+# endif
+#endif
+
 /* It should be possible to get rid of this by extending the feature-test
  * macros to cover Windows API functions, probably along with non-trivial
  * refactoring of code to find structures that sit more cleanly on top of

Modified: vendor/libarchive/dist/libarchive/archive_read_append_filter.c
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_read_append_filter.c	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/libarchive/archive_read_append_filter.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -89,6 +89,10 @@ archive_read_append_filter(struct archive *_a, int cod
       strcpy(str, "lz4");
       r1 = archive_read_support_filter_lz4(_a);
       break;
+    case ARCHIVE_FILTER_ZSTD:
+      strcpy(str, "zstd");
+      r1 = archive_read_support_filter_zstd(_a);
+      break;
     case ARCHIVE_FILTER_LZIP:
       strcpy(str, "lzip");
       r1 = archive_read_support_filter_lzip(_a);

Modified: vendor/libarchive/dist/libarchive/archive_read_disk_entry_from_file.c
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_read_disk_entry_from_file.c	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/libarchive/archive_read_disk_entry_from_file.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -127,7 +127,7 @@ archive_read_disk_entry_setup_acls(struct archive_read
 /*
  * Enter working directory and return working pathname of archive_entry.
  * If a pointer to an integer is provided and its value is below zero
- * open a file descriptor on this pahtname.
+ * open a file descriptor on this pathname.
  */
 const char *
 archive_read_disk_entry_setup_path(struct archive_read_disk *a,

Modified: vendor/libarchive/dist/libarchive/archive_read_filter.3
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_read_filter.3	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/libarchive/archive_read_filter.3	Sat Sep 30 23:33:19 2017	(r324145)
@@ -38,6 +38,7 @@
 .Nm archive_read_support_filter_rpm ,
 .Nm archive_read_support_filter_uu ,
 .Nm archive_read_support_filter_xz ,
+.Nm archive_read_support_filter_zstd ,
 .Nm archive_read_support_filter_program ,
 .Nm archive_read_support_filter_program_signature
 .Nd functions for reading streaming archives
@@ -73,6 +74,8 @@ Streaming Archive Library (libarchive, -larchive)
 .Ft int
 .Fn archive_read_support_filter_xz "struct archive *"
 .Ft int
+.Fn archive_read_support_filter_zstd "struct archive *"
+.Ft int
 .Fo archive_read_support_filter_program
 .Fa "struct archive *"
 .Fa "const char *cmd"
@@ -99,7 +102,8 @@ Streaming Archive Library (libarchive, -larchive)
 .Fn archive_read_support_filter_none ,
 .Fn archive_read_support_filter_rpm ,
 .Fn archive_read_support_filter_uu ,
-.Fn archive_read_support_filter_xz
+.Fn archive_read_support_filter_xz ,
+.Fn archive_read_support_filter_zstd ,
 .Xc
 Enables auto-detection code and decompression support for the
 specified compression.

Modified: vendor/libarchive/dist/libarchive/archive_read_support_filter_all.c
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_read_support_filter_all.c	Sat Sep 30 21:00:46 2017	(r324144)
+++ vendor/libarchive/dist/libarchive/archive_read_support_filter_all.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -71,6 +71,8 @@ archive_read_support_filter_all(struct archive *a)
 	archive_read_support_filter_grzip(a);
 	/* Lz4 falls back to "lz4 -d" command-line program. */
 	archive_read_support_filter_lz4(a);
+	/* Zstd falls back to "zstd -d" command-line program. */
+	archive_read_support_filter_zstd(a);
 
 	/* Note: We always return ARCHIVE_OK here, even if some of the
 	 * above return ARCHIVE_WARN.  The intent here is to enable

Added: vendor/libarchive/dist/libarchive/archive_read_support_filter_zstd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libarchive/dist/libarchive/archive_read_support_filter_zstd.c	Sat Sep 30 23:33:19 2017	(r324145)
@@ -0,0 +1,292 @@
+/*-
+ * Copyright (c) 2009-2011 Sean Purcell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ZSTD_H
+#include <zstd.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+
+struct private_data {
+	ZSTD_DStream	*dstream;
+	unsigned char	*out_block;
+	size_t		 out_block_size;
+	int64_t		 total_out;
+	char		 in_frame; /* True = in the middle of a zstd frame. */
+	char		 eof; /* True = found end of compressed data. */
+};
+
+/* Zstd Filter. */
+static ssize_t	zstd_filter_read(struct archive_read_filter *, const void**);
+static int	zstd_filter_close(struct archive_read_filter *);
+#endif
+
+/*
+ * Note that we can detect zstd compressed files even if we can't decompress
+ * them.  (In fact, we like detecting them because we can give better error
+ * messages.)  So the bid framework here gets compiled even if no zstd library
+ * is available.
+ */
+static int	zstd_bidder_bid(struct archive_read_filter_bidder *,
+		    struct archive_read_filter *);
+static int	zstd_bidder_init(struct archive_read_filter *);
+
+int
+archive_read_support_filter_zstd(struct archive *_a)
+{
+	struct archive_read *a = (struct archive_read *)_a;
+	struct archive_read_filter_bidder *bidder;
+
+	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_read_support_filter_zstd");
+
+	if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+		return (ARCHIVE_FATAL);
+
+	bidder->data = NULL;
+	bidder->name = "zstd";
+	bidder->bid = zstd_bidder_bid;
+	bidder->init = zstd_bidder_init;
+	bidder->options = NULL;
+	bidder->free = NULL;
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+	return (ARCHIVE_OK);
+#else
+	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+	    "Using external zstd program for zstd decompression");
+	return (ARCHIVE_WARN);
+#endif
+}
+
+/*
+ * Test whether we can handle this data.
+ */
+static int
+zstd_bidder_bid(struct archive_read_filter_bidder *self,
+    struct archive_read_filter *filter)
+{
+	const unsigned char *buffer;
+	ssize_t avail;
+	unsigned prefix;
+
+	/* Zstd frame magic values */
+	const unsigned zstd_magic = 0xFD2FB528U;
+
+	(void) self; /* UNUSED */
+
+	buffer = __archive_read_filter_ahead(filter, 4, &avail);
+	if (buffer == NULL)
+		return (0);
+
+	prefix = archive_le32dec(buffer);
+	if (prefix == zstd_magic)
+		return (32);
+
+	return (0);
+}
+
+#if !(HAVE_ZSTD_H && HAVE_LIBZSTD)
+
+/*
+ * If we don't have the library on this system, we can't do the
+ * decompression directly.  We can, however, try to run "zstd -d"
+ * in case that's available.
+ */
+static int
+zstd_bidder_init(struct archive_read_filter *self)
+{
+	int r;
+
+	r = __archive_read_program(self, "zstd -d -qq");
+	/* Note: We set the format here even if __archive_read_program()
+	 * above fails.  We do, after all, know what the format is
+	 * even if we weren't able to read it. */
+	self->code = ARCHIVE_FILTER_ZSTD;
+	self->name = "zstd";
+	return (r);
+}
+
+#else
+
+/*
+ * Initialize the filter object
+ */
+static int
+zstd_bidder_init(struct archive_read_filter *self)
+{
+	struct private_data *state;
+	const size_t out_block_size = ZSTD_DStreamOutSize();
+	void *out_block;
+	ZSTD_DStream *dstream;
+
+	self->code = ARCHIVE_FILTER_ZSTD;
+	self->name = "zstd";
+
+	state = (struct private_data *)calloc(sizeof(*state), 1);
+	out_block = (unsigned char *)malloc(out_block_size);
+	dstream = ZSTD_createDStream();
+
+	if (state == NULL || out_block == NULL || dstream == NULL) {
+		free(out_block);
+		free(state);
+		ZSTD_freeDStream(dstream); /* supports free on NULL */
+		archive_set_error(&self->archive->archive, ENOMEM,
+		    "Can't allocate data for zstd decompression");
+		return (ARCHIVE_FATAL);
+	}
+
+	self->data = state;
+
+	state->out_block_size = out_block_size;
+	state->out_block = out_block;
+	state->dstream = dstream;
+	self->read = zstd_filter_read;
+	self->skip = NULL; /* not supported */
+	self->close = zstd_filter_close;
+
+	state->eof = 0;
+	state->in_frame = 0;
+
+	return (ARCHIVE_OK);
+}
+
+static ssize_t
+zstd_filter_read(struct archive_read_filter *self, const void **p)
+{
+	struct private_data *state;
+	size_t decompressed;
+	ssize_t avail_in;
+	ZSTD_outBuffer out;
+	ZSTD_inBuffer in;
+
+	state = (struct private_data *)self->data;
+
+	out = (ZSTD_outBuffer) { state->out_block, state->out_block_size, 0 };
+
+	/* Try to fill the output buffer. */
+	while (out.pos < out.size && !state->eof) {
+		if (!state->in_frame) {
+			const size_t ret = ZSTD_initDStream(state->dstream);
+			if (ZSTD_isError(ret)) {
+				archive_set_error(&self->archive->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Error initializing zstd decompressor: %s",
+				    ZSTD_getErrorName(ret));
+				return (ARCHIVE_FATAL);
+			}
+		}
+		in.src = __archive_read_filter_ahead(self->upstream, 1,
+		    &avail_in);
+		if (avail_in < 0) {
+			return avail_in;
+		}
+		if (in.src == NULL && avail_in == 0) {
+			if (!state->in_frame) {
+				/* end of stream */
+				state->eof = 1;
+				break;
+			} else {
+				archive_set_error(&self->archive->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Truncated zstd input");
+				return (ARCHIVE_FATAL);
+			}
+		}
+		in.size = avail_in;
+		in.pos = 0;
+
+		{
+			const size_t ret =
+			    ZSTD_decompressStream(state->dstream, &out, &in);
+
+			if (ZSTD_isError(ret)) {
+				archive_set_error(&self->archive->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Zstd decompression failed: %s",
+				    ZSTD_getErrorName(ret));
+				return (ARCHIVE_FATAL);
+			}
+
+			/* Decompressor made some progress */
+			__archive_read_filter_consume(self->upstream, in.pos);
+
+			/* ret guaranteed to be > 0 if frame isn't done yet */
+			state->in_frame = (ret != 0);
+		}
+	}

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709302333.v8UNXJLc011212>