From 65da968c5ce7595908a244f509658357bf4bc49d Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Mon, 2 Mar 2020 02:12:53 +0000 Subject: [PATCH] Update vendor/libarchive/dist to git 85b9f665b6a2d4397fdd38992152d011265e374b Relevant vendor changes: Issue #1257: Add testcase for ZIPX files with LZMA_STREAM_END marker PR #1331: cpio.5: fix hard link description Issue #1335: archive_read.c: fix UBSan warning about undefined behavior Issue #1338: XAR reader: fix UBSan warning about undefined behavior Issue #1339: bsdcpio_test: fix datatype in from_hex() Issue #1341: Safe writes: delete temporary file if rename fails --- .cirrus.yml | 21 -------- .github/workflows/ci.yml | 4 +- CMakeLists.txt | 2 +- Makefile.am | 1 + build/ci/cirrus_ci/Dockerfile.fc30 | 3 -- ...kerfile.fc30.distcheck => Dockerfile.fc31} | 4 +- build/ci/cirrus_ci/Dockerfile.fc31.distcheck | 3 ++ build/ci/cirrus_ci/ci.sh | 6 ++- build/ci/github_actions/ci.cmd | 38 +++++++++++--- build/release/Dockerfile | 2 +- build/version | 2 +- configure.ac | 4 +- cpio/cpio.c | 15 +++--- cpio/cpio.h | 1 + cpio/test/test_format_newc.c | 33 ++++++------ libarchive/archive.h | 4 +- libarchive/archive_entry.h | 2 +- libarchive/archive_read.c | 17 ++++--- libarchive/archive_read_open_filename.c | 4 ++ libarchive/archive_read_support_format_xar.c | 17 +++++-- libarchive/archive_write_disk_posix.c | 6 ++- libarchive/archive_write_disk_windows.c | 6 ++- libarchive/archive_write_set_format.c | 2 +- libarchive/archive_write_set_format_xar.c | 3 +- libarchive/cpio.5 | 2 +- libarchive/test/test_read_format_zip.c | 50 +++++++++++++++++++ ...st_read_format_zip_lzma_stream_end.zipx.uu | 19 +++++++ 27 files changed, 186 insertions(+), 85 deletions(-) delete mode 100644 build/ci/cirrus_ci/Dockerfile.fc30 rename build/ci/cirrus_ci/{Dockerfile.fc30.distcheck => Dockerfile.fc31} (50%) create mode 100644 build/ci/cirrus_ci/Dockerfile.fc31.distcheck create mode 100644 libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu diff --git a/.cirrus.yml b/.cirrus.yml index bcc953582f0..d139c514258 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -26,27 +26,6 @@ FreeBSD_task: install_script: - ./build/ci/build.sh -a install -Fedora_30_task: - container: - dockerfile: build/ci/cirrus_ci/Dockerfile.fc30 - env: - matrix: - - BS: autotools - - BS: cmake - matrix: - - CRYPTO: mbedtls - - CRYPTO: nettle - - CRYPTO: openssl - configure_script: - - ./build/ci/build.sh -a autogen - - ./build/ci/build.sh -a configure - build_script: - - ./build/ci/build.sh -a build - test_script: - - ./build/ci/build.sh -a test - install_script: - - ./build/ci/build.sh -a install - Windows_Cygwin_task: windows_container: image: cirrusci/windowsservercore:2019 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ffa282479b..08299af372f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: steps: - uses: actions/checkout@master - name: Install dependencies - run: sudo apt-get install -y build-essential cmake libssl-dev nettle-dev libmbedtls-dev libacl1-dev libbz2-dev liblzma-dev libzip-dev liblz4-dev libzstd-dev lzop + run: sudo apt-get install -y build-essential cmake libssl-dev nettle-dev libmbedtls-dev libacl1-dev libbz2-dev liblzma-dev liblz4-dev libzstd-dev lzop - name: Autogen run: ./build/ci/build.sh -a autogen env: @@ -87,7 +87,7 @@ jobs: steps: - uses: actions/checkout@master - name: Install dependencies - run: sudo apt-get install -y build-essential cmake libssl-dev libacl1-dev libbz2-dev liblzma-dev libzip-dev liblz4-dev libzstd-dev lzop groff ghostscript + run: sudo apt-get install -y build-essential cmake libssl-dev libacl1-dev libbz2-dev liblzma-dev liblz4-dev libzstd-dev lzop groff ghostscript - name: Autogen run: ./build/ci/build.sh -a autogen - name: Configure diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a9b3250443..7a9f3d19ac0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ endif() # RelWithDebInfo : Release build with Debug Info # MinSizeRel : Release Min Size build IF(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE) + SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE) ENDIF(NOT CMAKE_BUILD_TYPE) # Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the # value type is "UNINITIALIZED". diff --git a/Makefile.am b/Makefile.am index 41b2808e9f7..78d674d5d06 100644 --- a/Makefile.am +++ b/Makefile.am @@ -915,6 +915,7 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/test_read_format_zip_lzma.zipx.uu \ libarchive/test/test_read_format_zip_lzma_alone_leak.zipx.uu \ libarchive/test/test_read_format_zip_lzma_multi.zipx.uu \ + libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu \ libarchive/test/test_read_format_zip_jar.jar.uu \ libarchive/test/test_read_format_zip_mac_metadata.zip.uu \ libarchive/test/test_read_format_zip_malformed1.zip.uu \ diff --git a/build/ci/cirrus_ci/Dockerfile.fc30 b/build/ci/cirrus_ci/Dockerfile.fc30 deleted file mode 100644 index 72a88bcc12b..00000000000 --- a/build/ci/cirrus_ci/Dockerfile.fc30 +++ /dev/null @@ -1,3 +0,0 @@ -FROM fedora:30 - -RUN dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel libasan librichacl-devel bzip2-devel libzip-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel nettle-devel mbedtls-devel diff --git a/build/ci/cirrus_ci/Dockerfile.fc30.distcheck b/build/ci/cirrus_ci/Dockerfile.fc31 similarity index 50% rename from build/ci/cirrus_ci/Dockerfile.fc30.distcheck rename to build/ci/cirrus_ci/Dockerfile.fc31 index 0129ec44e92..435f1d2063d 100644 --- a/build/ci/cirrus_ci/Dockerfile.fc30.distcheck +++ b/build/ci/cirrus_ci/Dockerfile.fc31 @@ -1,3 +1,3 @@ -FROM fedora:30 +FROM fedora:31 -RUN dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel libasan librichacl-devel bzip2-devel libzip-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel groff ghostscript xz zip +RUN dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel libasan librichacl-devel bzip2-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel nettle-devel mbedtls-devel diff --git a/build/ci/cirrus_ci/Dockerfile.fc31.distcheck b/build/ci/cirrus_ci/Dockerfile.fc31.distcheck new file mode 100644 index 00000000000..78b128990d2 --- /dev/null +++ b/build/ci/cirrus_ci/Dockerfile.fc31.distcheck @@ -0,0 +1,3 @@ +FROM fedora:31 + +RUN dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel libasan librichacl-devel bzip2-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel groff ghostscript xz zip diff --git a/build/ci/cirrus_ci/ci.sh b/build/ci/cirrus_ci/ci.sh index c07ebfe97be..27ef05c3c25 100755 --- a/build/ci/cirrus_ci/ci.sh +++ b/build/ci/cirrus_ci/ci.sh @@ -5,7 +5,9 @@ then if [ "${UNAME}" = "FreeBSD" ] then set -x -e + env ASSUME_ALWAYS_YES=yes pkg bootstrap -f sed -i.bak -e 's,pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly,pkg+http://pkg.FreeBSD.org/\${ABI}/latest,' /etc/pkg/FreeBSD.conf + pkg update mount -u -o acls / mkdir /tmp_acl_nfsv4 MD=`mdconfig -a -t swap -s 128M` @@ -27,10 +29,10 @@ then if [ -f "/etc/debian_version" ] then apt-get -y update - apt-get -y install build-essential locales automake libtool bison sharutils pkgconf libacl1-dev libbz2-dev libzip-dev zlib1g-dev liblzma-dev liblz4-dev libzstd-dev libssl-dev lrzip cmake + apt-get -y install build-essential locales automake libtool bison sharutils pkgconf libacl1-dev libbz2-dev zlib1g-dev liblzma-dev liblz4-dev libzstd-dev libssl-dev lrzip cmake elif [ -f "/etc/fedora-release" ] then - dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel librichacl-devel bzip2-devel libzip-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel + dnf -y install make cmake gcc gcc-c++ kernel-devel automake libtool bison sharutils pkgconf libacl-devel librichacl-devel bzip2-devel zlib-devel xz-devel lz4-devel libzstd-devel openssl-devel fi fi elif [ "$1" = "test" ] diff --git a/build/ci/github_actions/ci.cmd b/build/ci/github_actions/ci.cmd index 954d515c3b4..c3826ba0879 100755 --- a/build/ci/github_actions/ci.cmd +++ b/build/ci/github_actions/ci.cmd @@ -1,6 +1,7 @@ @ECHO OFF SET ZLIB_VERSION=1.2.11 SET BZIP2_VERSION=b7a672291188a6469f71dd13ad14f2f9a7344fc8 +SET XZ_VERSION=292a5c0f9c9b3a66f5a5c652dc46381836d4537f IF NOT "%BE%"=="mingw-gcc" ( IF NOT "%BE%"=="msvc" ( ECHO Environment variable BE must be mingw-gcc or msvc @@ -19,16 +20,28 @@ IF "%1"=="deplibs" ( ) CD build_ci\libs IF NOT EXIST zlib-%ZLIB_VERSION%.zip ( - curl -L -o zlib-%ZLIB_VERSION%.zip https://github.com/libarchive/zlib/archive/v%ZLIB_VERSION%.zip + ECHO Downloading https://github.com/libarchive/zlib/archive/v%ZLIB_VERSION%.zip + curl -L -o zlib-%ZLIB_VERSION%.zip https://github.com/libarchive/zlib/archive/v%ZLIB_VERSION%.zip || EXIT /b 1 ) IF NOT EXIST zlib-%ZLIB_VERSION% ( - tar -x -f zlib-%ZLIB_VERSION%.zip + ECHO Unpacking zlib-%ZLIB_VERSION%.zip + C:\windows\system32\tar.exe -x -f zlib-%ZLIB_VERSION%.zip || EXIT /b 1 ) IF NOT EXIST bzip2-%BZIP2_VERSION%.zip ( - curl -L -o bzip2-%BZIP2_VERSION%.zip https://github.com/libarchive/bzip2/archive/%BZIP2_VERSION%.zip + echo Downloading https://github.com/libarchive/bzip2/archive/%BZIP2_VERSION%.zip + curl -L -o bzip2-%BZIP2_VERSION%.zip https://github.com/libarchive/bzip2/archive/%BZIP2_VERSION%.zip || EXIT /b 1 ) IF NOT EXIST bzip2-%BZIP2_VERSION% ( - tar -x -f bzip2-%BZIP2_VERSION%.zip + echo Unpacking bzip2-%BZIP2_VERSION%.zip + C:\windows\system32\tar.exe -x -f bzip2-%BZIP2_VERSION%.zip || EXIT /b 1 + ) + IF NOT EXIST xz-%XZ_VERSION%.zip ( + echo Downloading https://github.com/libarchive/xz/archive/%XZ_VERSION%.zip + curl -L -o xz-%XZ_VERSION%.zip https://github.com/libarchive/xz/archive/%XZ_VERSION%.zip || EXIT /b 1 + ) + IF NOT EXIST xz-%XZ_VERSION% ( + echo Unpacking xz-%XZ_VERSION%.zip + C:\windows\system32\tar.exe -x -f xz-%XZ_VERSION%.zip || EXIT /b 1 ) CD zlib-%ZLIB_VERSION% IF "%BE%"=="mingw-gcc" ( @@ -58,16 +71,27 @@ IF "%1"=="deplibs" ( cmake --build . --target INSTALL --config Release || EXIT /b 1 ) CD .. + CD xz-%XZ_VERSION% + IF "%BE%"=="mingw-gcc" ( + SET PATH=%MINGWPATH% + cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE="Release" . || EXIT /b 1 + mingw32-make || EXIT /b 1 + mingw32-make install || EXIT /b 1 + ) ELSE IF "%BE%"=="msvc" ( + cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE="Release" . || EXIT /b 1 + cmake --build . --target ALL_BUILD --config Release || EXIT /b 1 + cmake --build . --target INSTALL --config Release || EXIT /b 1 + ) ) ELSE IF "%1%"=="configure" ( IF "%BE%"=="mingw-gcc" ( SET PATH=%MINGWPATH% MKDIR build_ci\cmake CD build_ci\cmake - cmake -G "MinGW Makefiles" -D ZLIB_LIBRARY="C:/Program Files (x86)/zlib/lib/libzlibstatic.a" -D ZLIB_INCLUDE_DIR="C:/Program Files (x86)/zlib/include" -D BZIP2_LIBRARIES="C:/Program Files (x86)/bzip2/lib/libbz2.a" -D BZIP2_INCLUDE_DIR="C:/Program Files (x86)/bzip2/include" ..\.. || EXIT /b 1 + cmake -G "MinGW Makefiles" -D ZLIB_LIBRARY="C:/Program Files (x86)/zlib/lib/libzlibstatic.a" -D ZLIB_INCLUDE_DIR="C:/Program Files (x86)/zlib/include" -D BZIP2_LIBRARIES="C:/Program Files (x86)/bzip2/lib/libbz2.a" -D BZIP2_INCLUDE_DIR="C:/Program Files (x86)/bzip2/include" -D LIBLZMA_LIBRARY="C:/Program Files (x86)/xz/lib/liblzma.a" -D LIBLZMA_INCLUDE_DIR="C:/Program Files (x86)/xz/include" ..\.. || EXIT /b 1 ) ELSE IF "%BE%"=="msvc" ( MKDIR build_ci\cmake CD build_ci\cmake - cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE="Release" -D ZLIB_LIBRARY="C:/Program Files (x86)/zlib/lib/zlibstatic.lib" -D ZLIB_INCLUDE_DIR="C:/Program Files (x86)/zlib/include" -D BZIP2_LIBRARIES="C:/Program Files (x86)/bzip2/lib/bz2.lib" -D BZIP2_INCLUDE_DIR="C:/Program Files (x86)/bzip2/include" ..\.. || EXIT /b 1 + cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE="Release" -D ZLIB_LIBRARY="C:/Program Files (x86)/zlib/lib/zlibstatic.lib" -D ZLIB_INCLUDE_DIR="C:/Program Files (x86)/zlib/include" -D BZIP2_LIBRARIES="C:/Program Files (x86)/bzip2/lib/bz2.lib" -D BZIP2_INCLUDE_DIR="C:/Program Files (x86)/bzip2/include" -D LIBLZMA_LIBRARY="C:/Program Files (x86)/xz/lib/liblzma.lib" -D LIBLZMA_INCLUDE_DIR="C:/Program Files (x86)/xz/include" ..\.. || EXIT /b 1 ) ) ELSE IF "%1%"=="build" ( IF "%BE%"=="mingw-gcc" ( @@ -100,7 +124,7 @@ IF "%1"=="deplibs" ( cmake --build . --target INSTALL --config Release || EXIT /b 1 ) ) ELSE IF "%1"=="artifact" ( - tar -c -C "C:\Program Files (x86)" --format=zip -f libarchive.zip libarchive + C:\windows\system32\tar.exe -c -C "C:\Program Files (x86)" --format=zip -f libarchive.zip libarchive ) ELSE ( ECHO "Usage: %0% deplibs|configure|build|test|install|artifact" @EXIT /b 0 diff --git a/build/release/Dockerfile b/build/release/Dockerfile index 76944f40c48..fc920b6ec8b 100644 --- a/build/release/Dockerfile +++ b/build/release/Dockerfile @@ -1,5 +1,5 @@ FROM ubuntu:18.04 -RUN apt-get update && apt-get install -y build-essential autoconf automake libtool pkg-config cmake libssl-dev libacl1-dev libbz2-dev liblzma-dev libzip-dev liblz4-dev libzstd-dev lzop groff ghostscript bsdmainutils zip +RUN apt-get update && apt-get install -y build-essential autoconf automake libtool pkg-config cmake libssl-dev libacl1-dev libbz2-dev liblzma-dev liblz4-dev libzstd-dev lzop groff ghostscript bsdmainutils zip ADD . $HOME/libarchive/ ADD "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD" $HOME/libarchive/build/autoconf/config.guess ADD "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD" $HOME/libarchive/build/autoconf/config.sub diff --git a/build/version b/build/version index 78be3ab7e34..c4da5ab0994 100644 --- a/build/version +++ b/build/version @@ -1 +1 @@ -3004002 +3004003dev diff --git a/configure.ac b/configure.ac index 2581087988b..1f533665565 100644 --- a/configure.ac +++ b/configure.ac @@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front. dnl In particular, this allows the version macro to be used in AC_INIT dnl These first two version numbers are updated automatically on each release. -m4_define([LIBARCHIVE_VERSION_S],[3.4.2]) -m4_define([LIBARCHIVE_VERSION_N],[3004002]) +m4_define([LIBARCHIVE_VERSION_S],[3.4.3dev]) +m4_define([LIBARCHIVE_VERSION_N],[3004003]) dnl bsdtar and bsdcpio versioning tracks libarchive m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S()) diff --git a/cpio/cpio.c b/cpio/cpio.c index da5c3986001..c15ee525f06 100644 --- a/cpio/cpio.c +++ b/cpio/cpio.c @@ -737,7 +737,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath) */ destpath = srcpath; if (cpio->destdir) { - len = strlen(cpio->destdir) + strlen(srcpath) + 8; + len = cpio->destdir_len + strlen(srcpath) + 8; if (len >= cpio->pass_destpath_alloc) { while (len >= cpio->pass_destpath_alloc) { cpio->pass_destpath_alloc += 512; @@ -1228,15 +1228,14 @@ mode_pass(struct cpio *cpio, const char *destdir) struct lafe_line_reader *lr; const char *p; int r; - size_t destdir_len; /* Ensure target dir has a trailing '/' to simplify path surgery. */ - destdir_len = strlen(destdir); - cpio->destdir = malloc(destdir_len + 8); - memcpy(cpio->destdir, destdir, destdir_len); - if (destdir_len == 0 || destdir[destdir_len - 1] != '/') - cpio->destdir[destdir_len++] = '/'; - cpio->destdir[destdir_len++] = '\0'; + cpio->destdir_len = strlen(destdir); + cpio->destdir = malloc(cpio->destdir_len + 8); + memcpy(cpio->destdir, destdir, cpio->destdir_len); + if (cpio->destdir_len == 0 || destdir[cpio->destdir_len - 1] != '/') + cpio->destdir[cpio->destdir_len++] = '/'; + cpio->destdir[cpio->destdir_len] = '\0'; cpio->archive = archive_write_disk_new(); if (cpio->archive == NULL) diff --git a/cpio/cpio.h b/cpio/cpio.h index abf3628bfae..8e7cc5fdd20 100644 --- a/cpio/cpio.h +++ b/cpio/cpio.h @@ -64,6 +64,7 @@ struct cpio { int option_numeric_uid_gid; /* -n */ int option_rename; /* -r */ char *destdir; + size_t destdir_len; size_t pass_destpath_alloc; char *pass_destpath; int uid_override; diff --git a/cpio/test/test_format_newc.c b/cpio/test/test_format_newc.c index 49387a73580..6e3b9e359bb 100644 --- a/cpio/test/test_format_newc.c +++ b/cpio/test/test_format_newc.c @@ -49,10 +49,11 @@ is_hex(const char *p, size_t l) return (1); } -static int +/* Convert up to 8 hex characters to unsigned 32-bit decimal integer */ +static uint32_t from_hex(const char *p, size_t l) { - int r = 0; + uint32_t r = 0; while (l > 0) { r *= 16; @@ -82,11 +83,11 @@ DEFINE_TEST(test_format_newc) { FILE *list; int r; - int devmajor, devminor, ino, gid; - int uid = -1; + uint32_t devmajor, devminor, ino, gid, uid; time_t t, t2, now; char *p, *e; - size_t s, fs, ns; + size_t s; + uint64_t fs, ns; char result[1024]; assertUmask(0); @@ -199,9 +200,11 @@ DEFINE_TEST(test_format_newc) #else assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */ #endif - if (uid < 0) - uid = from_hex(e + 22, 8); +#if defined(_WIN32) + uid = from_hex(e + 22, 8); +#else assertEqualInt(from_hex(e + 22, 8), uid); /* uid */ +#endif gid = from_hex(e + 30, 8); /* gid */ assertEqualMem(e + 38, "00000003", 8); /* nlink */ t = from_hex(e + 46, 8); /* mtime */ @@ -215,14 +218,14 @@ DEFINE_TEST(test_format_newc) " first appearance should be empty, so this file size\n" " field should be zero"); assertEqualInt(0, from_hex(e + 54, 8)); /* File size */ - fs = from_hex(e + 54, 8); + fs = (uint64_t)from_hex(e + 54, 8); fs += PAD(fs, 4); devmajor = from_hex(e + 62, 8); /* devmajor */ devminor = from_hex(e + 70, 8); /* devminor */ assert(is_hex(e + 78, 8)); /* rdevmajor */ assert(is_hex(e + 86, 8)); /* rdevminor */ assertEqualMem(e + 94, "00000006", 8); /* Name size */ - ns = from_hex(e + 94, 8); + ns = (uint64_t)from_hex(e + 94, 8); ns += PAD(ns + 2, 4); assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ assertEqualMem(e + 110, "file1\0", 6); /* Name contents */ @@ -249,14 +252,14 @@ DEFINE_TEST(test_format_newc) " at t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualMem(e + 54, "00000005", 8); /* File size */ - fs = from_hex(e + 54, 8); + fs = (uint64_t)from_hex(e + 54, 8); fs += PAD(fs, 4); assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ assert(is_hex(e + 78, 8)); /* rdevmajor */ assert(is_hex(e + 86, 8)); /* rdevminor */ assertEqualMem(e + 94, "00000008", 8); /* Name size */ - ns = from_hex(e + 94, 8); + ns = (uint64_t)from_hex(e + 94, 8); ns += PAD(ns + 2, 4); assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */ @@ -285,14 +288,14 @@ DEFINE_TEST(test_format_newc) "t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualMem(e + 54, "00000000", 8); /* File size */ - fs = from_hex(e + 54, 8); + fs = (uint64_t)from_hex(e + 54, 8); fs += PAD(fs, 4); assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ assert(is_hex(e + 78, 8)); /* rdevmajor */ assert(is_hex(e + 86, 8)); /* rdevminor */ assertEqualMem(e + 94, "00000004", 8); /* Name size */ - ns = from_hex(e + 94, 8); + ns = (uint64_t)from_hex(e + 94, 8); ns += PAD(ns + 2, 4); assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */ @@ -319,14 +322,14 @@ DEFINE_TEST(test_format_newc) "t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualInt(10, from_hex(e + 54, 8)); /* File size */ - fs = from_hex(e + 54, 8); + fs = (uint64_t)from_hex(e + 54, 8); fs += PAD(fs, 4); assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ assert(is_hex(e + 78, 8)); /* rdevmajor */ assert(is_hex(e + 86, 8)); /* rdevminor */ assertEqualMem(e + 94, "00000009", 8); /* Name size */ - ns = from_hex(e + 94, 8); + ns = (uint64_t)from_hex(e + 94, 8); ns += PAD(ns + 2, 4); assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */ diff --git a/libarchive/archive.h b/libarchive/archive.h index 55818eac8e6..b984ef3f8e0 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -36,7 +36,7 @@ * assert that ARCHIVE_VERSION_NUMBER >= 2012108. */ /* Note: Compiler will complain if this does not match archive_entry.h! */ -#define ARCHIVE_VERSION_NUMBER 3004002 +#define ARCHIVE_VERSION_NUMBER 3004003 #include #include /* for wchar_t */ @@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void); /* * Textual name/version of the library, useful for version displays. */ -#define ARCHIVE_VERSION_ONLY_STRING "3.4.2" +#define ARCHIVE_VERSION_ONLY_STRING "3.4.3dev" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h index 42af20864f7..90768256eff 100644 --- a/libarchive/archive_entry.h +++ b/libarchive/archive_entry.h @@ -30,7 +30,7 @@ #define ARCHIVE_ENTRY_H_INCLUDED /* Note: Compiler will complain if this does not match archive.h! */ -#define ARCHIVE_VERSION_NUMBER 3004002 +#define ARCHIVE_VERSION_NUMBER 3004003 /* * Note: archive_entry.h is for use outside of libarchive; the diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c index 4a933b2fc08..c59f0515349 100644 --- a/libarchive/archive_read.c +++ b/libarchive/archive_read.c @@ -892,15 +892,16 @@ archive_read_data(struct archive *_a, void *buff, size_t s) len = a->read_data_remaining; if (len > s) len = s; - if (len) + if (len) { memcpy(dest, a->read_data_block, len); - s -= len; - a->read_data_block += len; - a->read_data_remaining -= len; - a->read_data_output_offset += len; - a->read_data_offset += len; - dest += len; - bytes_read += len; + s -= len; + a->read_data_block += len; + a->read_data_remaining -= len; + a->read_data_output_offset += len; + a->read_data_offset += len; + dest += len; + bytes_read += len; + } } } a->read_data_is_posix_read = 0; diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c index 86635e21928..561289b694b 100644 --- a/libarchive/archive_read_open_filename.c +++ b/libarchive/archive_read_open_filename.c @@ -221,7 +221,9 @@ file_open(struct archive *a, void *client_data) struct read_file_data *mine = (struct read_file_data *)client_data; void *buffer; const char *filename = NULL; +#if defined(_WIN32) && !defined(__CYGWIN__) const wchar_t *wfilename = NULL; +#endif int fd = -1; int is_disk_like = 0; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) @@ -281,10 +283,12 @@ file_open(struct archive *a, void *client_data) #endif } if (fstat(fd, &st) != 0) { +#if defined(_WIN32) && !defined(__CYGWIN__) if (mine->filename_type == FNT_WCS) archive_set_error(a, errno, "Can't stat '%S'", wfilename); else +#endif archive_set_error(a, errno, "Can't stat '%s'", filename); goto fail; diff --git a/libarchive/archive_read_support_format_xar.c b/libarchive/archive_read_support_format_xar.c index 7f8be398c7a..503ff58b91d 100644 --- a/libarchive/archive_read_support_format_xar.c +++ b/libarchive/archive_read_support_format_xar.c @@ -458,6 +458,11 @@ archive_read_support_format_xar(struct archive *_a) return (ARCHIVE_FATAL); } + /* initialize xar->file_queue */ + xar->file_queue.allocated = 0; + xar->file_queue.used = 0; + xar->file_queue.files = NULL; + r = __archive_read_register_format(a, xar, "xar", @@ -1221,10 +1226,12 @@ heap_add_entry(struct archive_read *a, /* Expand our pending files list as necessary. */ if (heap->used >= heap->allocated) { struct xar_file **new_pending_files; - int new_size = heap->allocated * 2; + int new_size; if (heap->allocated < 1024) new_size = 1024; + else + new_size = heap->allocated * 2; /* Overflow might keep us from growing the list. */ if (new_size <= heap->allocated) { archive_set_error(&a->archive, @@ -1238,9 +1245,11 @@ heap_add_entry(struct archive_read *a, ENOMEM, "Out of memory"); return (ARCHIVE_FATAL); } - memcpy(new_pending_files, heap->files, - heap->allocated * sizeof(new_pending_files[0])); - free(heap->files); + if (heap->allocated) { + memcpy(new_pending_files, heap->files, + heap->allocated * sizeof(new_pending_files[0])); + free(heap->files); + } heap->files = new_pending_files; heap->allocated = new_size; } diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c index cc53a3d318e..35b5aedf7f0 100644 --- a/libarchive/archive_write_disk_posix.c +++ b/libarchive/archive_write_disk_posix.c @@ -1654,6 +1654,7 @@ _archive_write_disk_finish_entry(struct archive *_a) { struct archive_write_disk *a = (struct archive_write_disk *)_a; int ret = ARCHIVE_OK; + int oerrno; archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, @@ -1855,8 +1856,11 @@ finish_metadata: a->fd = -1; if (a->tmpname) { if (rename(a->tmpname, a->name) == -1) { + oerrno = errno; + unlink(a->tmpname); + errno = oerrno; archive_set_error(&a->archive, errno, - "rename failed"); + "Failed to safe write"); ret = ARCHIVE_FATAL; } a->tmpname = NULL; diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c index 77e36c4a621..4b703492b14 100644 --- a/libarchive/archive_write_disk_windows.c +++ b/libarchive/archive_write_disk_windows.c @@ -1174,6 +1174,7 @@ _archive_write_disk_finish_entry(struct archive *_a) { struct archive_write_disk *a = (struct archive_write_disk *)_a; int ret = ARCHIVE_OK; + int oerrno; archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, @@ -1281,8 +1282,11 @@ _archive_write_disk_finish_entry(struct archive *_a) /* Windows does not support atomic rename */ disk_unlink(a->name); if (_wrename(a->tmpname, a->name) != 0) { + oerrno = errno; + disk_unlink(a->tmpname); + errno = oerrno; archive_set_error(&a->archive, errno, - "rename failed"); + "Failed to safe write"); ret = ARCHIVE_FATAL; } a->tmpname = NULL; diff --git a/libarchive/archive_write_set_format.c b/libarchive/archive_write_set_format.c index 12de0807753..7dbe7b9a2c1 100644 --- a/libarchive/archive_write_set_format.c +++ b/libarchive/archive_write_set_format.c @@ -82,7 +82,7 @@ void __archive_write_entry_filetype_unsupported(struct archive *a, struct archive_entry *entry, const char *format) { - char *name = NULL; + const char *name = NULL; switch (archive_entry_filetype(entry)) { /* diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c index d456cf8f8aa..e1c7f3a96d4 100644 --- a/libarchive/archive_write_set_format_xar.c +++ b/libarchive/archive_write_set_format_xar.c @@ -681,7 +681,8 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s) { struct xar *xar; enum la_zaction run; - size_t size, rsize; + size_t size = 0; + size_t rsize; int r; xar = (struct xar *)a->format_data; diff --git a/libarchive/cpio.5 b/libarchive/cpio.5 index 1a2886f0867..a91f0c596d2 100644 --- a/libarchive/cpio.5 +++ b/libarchive/cpio.5 @@ -244,7 +244,7 @@ Note that this format supports only 4 gigabyte files (unlike the older ASCII format, which supports 8 gigabyte files). .Pp In this format, hardlinked files are handled by setting the -filesize to zero for each entry except the last one that +filesize to zero for each entry except the first one that appears in the archive. .Ss New CRC Format The CRC format is identical to the new ASCII format described diff --git a/libarchive/test/test_read_format_zip.c b/libarchive/test/test_read_format_zip.c index 04f7e98ccfc..04dfecb015f 100644 --- a/libarchive/test/test_read_format_zip.c +++ b/libarchive/test/test_read_format_zip.c @@ -916,3 +916,53 @@ DEFINE_TEST(test_read_format_zip_lzma_alone_leak) * suite under Valgrind or ASan, the test runner won't return with * exit code 0 in case if a memory leak. */ } + +DEFINE_TEST(test_read_format_zip_lzma_stream_end) +{ + const char *refname = "test_read_format_zip_lzma_stream_end.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_lzma_stream_end_blockread) +{ + const char *refname = "test_read_format_zip_lzma_stream_end.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} diff --git a/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu b/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu new file mode 100644 index 00000000000..2b79bc221e0 --- /dev/null +++ b/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu @@ -0,0 +1,19 @@ +begin 664 test_read_format_zip_lzma_stream_end.zipx +M4$L#!#\``@`.`#TQD4VJ.XZZ/@(``)`#```%````=FEM)82Q1PWAL +M+U`,N0L_$]^&650C/X$D6#4QFD$\A/"_![4!O/5O/!KH`WCQ*4?T2*]4P#/D +M0'9I?EZG=N69Z0V;H0I=CP*$?".I\ +MGMG/80.A'^W>R4J'S/CZ%P`8`>F=R>R&R$2T@EM#X)"OQH1?A7,`:4IU9WV! +M#2W*DXT',;.4YIN4A:-X)O=IREL201ZSOC=YSAU[C4-::/YV8\)%"L17+>VC +M%/'B]ZCQN$2(Q*9*\KJZ`Y131`]5C&G';@1S-QES_RZF!2OX45@58+??ES%( +MUJ<(\`11M$NO)HK#/MK-9RT"15.2I:IZN8VTM1_?$G\L#BH67]$S%[4 +M%C-$\Q<+./&HV](4,7)OL-@C^M0F"2O!0N$OHOW54H87^QLBQVH*D%A<#SI% +M/#+-5U(W';:KC)RE>0Y^5YI!RECQNR"R4.UW9IR!@:B!UB8?_D5$FT8YCJHJ +M2[2"-&-_D2BJ6#XK[6G=%K"%;'^-+0]FHCY4ER#`^