From f9b2e63a44664e352e4a767f2822ca3eda65f540 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Mon, 25 Mar 2019 11:39:49 +0000 Subject: Update vendor/libarchive/dist to git 3c079320b23ddf5ef38c443569c25898ad79ddb9 Relevant vendor changes: PR #1153: fixed 2 bugs in ZIP reader PR #1143: ensure archive_read_disk_entry_from_file() uses ARCHIVE_READ_DISK Changes to file flags code, support more file flags on FreeBSD: UF_OFFLINE, UF_READONLY, UF_SPARSE, UF_REPARSE, UF_SYSTEM UF_ARCHIVE is not supported by intention (yet) --- .travis.yml | 9 + CMakeLists.txt | 26 +- Makefile.am | 2 + build/ci/travis_ci.sh | 32 +++ libarchive/CMakeLists.txt | 1 + libarchive/archive_blake2sp_ref.c | 6 +- libarchive/archive_entry.c | 262 +++++++++++---------- libarchive/archive_read_disk_entry_from_file.c | 3 + libarchive/archive_read_support_format_rar5.c | 29 +-- libarchive/archive_read_support_format_zip.c | 29 ++- libarchive/archive_string.c | 6 +- libarchive/archive_write_disk_posix.c | 126 ++++++---- libarchive/archive_write_disk_windows.c | 5 + libarchive/archive_write_set_format_7zip.c | 3 +- libarchive/test/test_entry.c | 2 +- libarchive/test/test_read_format_rar5.c | 26 +- libarchive/test/test_read_format_xar.c | 10 +- libarchive/test/test_read_format_zip.c | 66 +++++- .../test/test_read_format_zip_bz2_hang.zip.uu | 5 + .../test_read_format_zip_ppmd8_crash_1.zipx.uu | 4 + .../test_read_format_zip_ppmd8_crash_2.zipx.uu | 4 + 21 files changed, 429 insertions(+), 227 deletions(-) create mode 100644 .travis.yml create mode 100755 build/ci/travis_ci.sh create mode 100644 libarchive/test/test_read_format_zip_bz2_hang.zip.uu create mode 100644 libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu create mode 100644 libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000000..12ed598f6599 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: C +matrix: + include: + - os: windows + env: BS=msbuild + - os: windows + env: BS=mingw +script: + - build/ci/travis_ci.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index bd609eb408eb..133a5ddc50ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ # CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR) +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``_ROOT`` variables. +endif() # PROJECT(libarchive C) # @@ -84,6 +87,11 @@ SET(CMAKE_REQUIRED_DEFINITIONS) SET(CMAKE_REQUIRED_INCLUDES) SET(CMAKE_REQUIRED_LIBRARIES) SET(CMAKE_REQUIRED_FLAGS) +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." ON) +else () + OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." OFF) +endif () # Especially for early development, we want to be a little # aggressive about diagnosing build problems; this can get @@ -93,10 +101,12 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$") ################################################################# # Set compile flags for all build types. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security") + if (ENABLE_WERROR) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + endif () ################################################################# # Set compile flags for debug build. # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug" - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow") @@ -108,11 +118,13 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^Clang$") ################################################################# # Set compile flags for all build types. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security") + if (ENABLE_WERROR) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + endif () ################################################################# # Set compile flags for debug build. # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug" SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow") @@ -125,15 +137,21 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^XL$") ################################################################# # Set compile flags for all build types. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qflag=e:e -qformat=sec") + if (ENABLE_WERROR) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qhalt=w") + endif () ################################################################# # Set compile flags for debug build. # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug" SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qhalt=w") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qflag=w:w") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qinfo=pro:use") ENDIF(CMAKE_C_COMPILER_ID MATCHES "^XL$") IF (MSVC) + if (ENABLE_WERROR) + # /WX option is the same as gcc's -Werror option. + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") + endif () ################################################################# # Set compile flags for debug build. # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug" @@ -165,8 +183,6 @@ IF (MSVC) # Enable level 4 C4706: The test value in a conditional expression was the # result of an assignment. SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4706") - # /WX option is the same as gcc's -Werror option. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /WX") # /Oi option enables built-in functions. SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi") ################################################################# diff --git a/Makefile.am b/Makefile.am index 0e8056be1aca..186126bec280 100644 --- a/Makefile.am +++ b/Makefile.am @@ -256,6 +256,8 @@ endif if INC_BLAKE2 libarchive_la_SOURCES+= \ + libarchive/archive_blake2.h \ + libarchive/archive_blake2_impl.h \ libarchive/archive_blake2s_ref.c \ libarchive/archive_blake2sp_ref.c endif diff --git a/build/ci/travis_ci.sh b/build/ci/travis_ci.sh new file mode 100755 index 000000000000..e51a67931b9f --- /dev/null +++ b/build/ci/travis_ci.sh @@ -0,0 +1,32 @@ +#!/bin/sh +set -e +UNAME=`uname` +CURDIR=`pwd` +SRCDIR="${SRCDIR:-`pwd`}" +if [ -z "${BUILDDIR}" ]; then + BUILDDIR="${CURDIR}/build_ci/${BS}" +fi +mkdir -p "${BUILDDIR}" +cd "${BUILDDIR}" +case "$UNAME" in + MSYS*) + if [ "${BS}" = "msbuild" ]; then + set -x + cmake -G "Visual Studio 15 2017" -D CMAKE_BUILD_TYPE="Release" "${SRCDIR}" + cmake --build . --target ALL_BUILD + # Until fixed, we don't run tests on Windows (lots of fails + timeout) + #cmake --build . --target RUN_TESTS + set +x + elif [ "${BS}" = "mingw" ]; then + set -x + cmake -G "MSYS Makefiles" -D CMAKE_C_COMPILER="${CC}" -D CMAKE_MAKE_PROGRAM="mingw32-make" -D CMAKE_BUILD_TYPE="Release" "${SRCDIR}" + mingw32-make + # The MinGW tests time out on Travis CI, disable for now + #mingw32-make test + set +x + else + echo "Unknown or unspecified build type: ${BS}" + exit 1 + fi + ;; +esac diff --git a/libarchive/CMakeLists.txt b/libarchive/CMakeLists.txt index 8e86aade2266..2bc69593d038 100644 --- a/libarchive/CMakeLists.txt +++ b/libarchive/CMakeLists.txt @@ -235,6 +235,7 @@ ENDIF() # Libarchive is a shared library ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS}) +TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .) TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS}) SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION}) diff --git a/libarchive/archive_blake2sp_ref.c b/libarchive/archive_blake2sp_ref.c index 90a385775d78..aef101084a8b 100644 --- a/libarchive/archive_blake2sp_ref.c +++ b/libarchive/archive_blake2sp_ref.c @@ -89,7 +89,7 @@ int blake2sp_init( blake2sp_state *S, size_t outlen ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; + if( blake2sp_init_leaf( S->S[i], outlen, 0, (uint32_t)i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; @@ -112,7 +112,7 @@ int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; + if( blake2sp_init_leaf( S->S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; @@ -230,7 +230,7 @@ int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void if( keylen > BLAKE2S_KEYBYTES ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; + if( blake2sp_init_leaf( S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c index 5125a2eb284e..34cd581155b2 100644 --- a/libarchive/archive_entry.c +++ b/libarchive/archive_entry.c @@ -1632,6 +1632,51 @@ _archive_entry_acl_text_l(struct archive_entry *entry, int flags, * SUCH DAMAGE. */ +/* + * Supported file flags on FreeBSD and Mac OS: + * sappnd,sappend SF_APPEND + * arch,archived SF_ARCHIVED + * schg,schange,simmutable SF_IMMUTABLE + * sunlnk,sunlink SF_NOUNLINK (FreeBSD only) + * uappnd,uappend UF_APPEND + * compressed UF_COMPRESSED (Mac OS only) + * hidden,uhidden UF_HIDDEN + * uchg,uchange,uimmutable UF_IMMUTABLE + * nodump UF_NODUMP + * uunlnk,uunlink UF_NOUNLINK (FreeBSD only) + * offline,uoffline UF_OFFLINE (FreeBSD only) + * opaque UF_OPAQUE + * rdonly,urdonly,readonly UF_READONLY (FreeBSD only) + * reparse,ureparse UF_REPARSE (FreeBSD only) + * sparse,usparse UF_SPARSE (FreeBSD only) + * system,usystem UF_SYSTEM (FreeBSD only) + * + * See chflags(2) for more information + * + * Supported file attributes on Linux: + * a append only FS_APPEND_FL sappnd + * A no atime updates FS_NOATIME_FL atime + * c compress FS_COMPR_FL compress + * C no copy on write FS_NOCOW_FL cow + * d no dump FS_NODUMP_FL dump + * D synchronous directory updates FS_DIRSYNC_FL dirsync + * i immutable FS_IMMUTABLE_FL schg + * j data journalling FS_JOURNAL_DATA_FL journal + * P project hierarchy FS_PROJINHERIT_FL projinherit + * s secure deletion FS_SECRM_FL securedeletion + * S synchronous updates FS_SYNC_FL sync + * t no tail-merging FS_NOTAIL_FL tail + * T top of directory hierarchy FS_TOPDIR_FL topdir + * u undeletable FS_UNRM_FL undel + * + * See ioctl_iflags(2) for more information + * + * Equivalent file flags supported on FreeBSD / Mac OS and Linux: + * SF_APPEND FS_APPEND_FL sappnd + * SF_IMMUTABLE FS_IMMUTABLE_FL schg + * UF_NODUMP FS_NODUMP_FL nodump + */ + static const struct flag { const char *name; const wchar_t *wname; @@ -1640,190 +1685,149 @@ static const struct flag { } flags[] = { /* Preferred (shorter) names per flag first, all prefixed by "no" */ #ifdef SF_APPEND - { "nosappnd", L"nosappnd", SF_APPEND, 0 }, - { "nosappend", L"nosappend", SF_APPEND, 0 }, + { "nosappnd", L"nosappnd", SF_APPEND, 0}, + { "nosappend", L"nosappend", SF_APPEND, 0}, #endif #if defined(FS_APPEND_FL) /* 'a' */ - { "nosappnd", L"nosappnd", FS_APPEND_FL, 0 }, - { "nosappend", L"nosappend", FS_APPEND_FL, 0 }, + { "nosappnd", L"nosappnd", FS_APPEND_FL, 0}, + { "nosappend", L"nosappend", FS_APPEND_FL, 0}, #elif defined(EXT2_APPEND_FL) /* 'a' */ - { "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0 }, - { "nosappend", L"nosappend", EXT2_APPEND_FL, 0 }, + { "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0}, + { "nosappend", L"nosappend", EXT2_APPEND_FL, 0}, #endif #ifdef SF_ARCHIVED - { "noarch", L"noarch", SF_ARCHIVED, 0 }, - { "noarchived", L"noarchived", SF_ARCHIVED, 0 }, + { "noarch", L"noarch", SF_ARCHIVED, 0}, + { "noarchived", L"noarchived", SF_ARCHIVED, 0}, #endif #ifdef SF_IMMUTABLE - { "noschg", L"noschg", SF_IMMUTABLE, 0 }, - { "noschange", L"noschange", SF_IMMUTABLE, 0 }, - { "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0 }, + { "noschg", L"noschg", SF_IMMUTABLE, 0}, + { "noschange", L"noschange", SF_IMMUTABLE, 0}, + { "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0}, #endif #if defined(FS_IMMUTABLE_FL) /* 'i' */ - { "noschg", L"noschg", FS_IMMUTABLE_FL, 0 }, - { "noschange", L"noschange", FS_IMMUTABLE_FL, 0 }, - { "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0 }, + { "noschg", L"noschg", FS_IMMUTABLE_FL, 0}, + { "noschange", L"noschange", FS_IMMUTABLE_FL, 0}, + { "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0}, #elif defined(EXT2_IMMUTABLE_FL) /* 'i' */ - { "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0 }, - { "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0 }, - { "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0 }, + { "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0}, + { "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0}, + { "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0}, #endif #ifdef SF_NOUNLINK - { "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0 }, - { "nosunlink", L"nosunlink", SF_NOUNLINK, 0 }, -#endif -#ifdef SF_SNAPSHOT - { "nosnapshot", L"nosnapshot", SF_SNAPSHOT, 0 }, + { "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0}, + { "nosunlink", L"nosunlink", SF_NOUNLINK, 0}, #endif #ifdef UF_APPEND - { "nouappnd", L"nouappnd", UF_APPEND, 0 }, - { "nouappend", L"nouappend", UF_APPEND, 0 }, + { "nouappnd", L"nouappnd", UF_APPEND, 0}, + { "nouappend", L"nouappend", UF_APPEND, 0}, #endif #ifdef UF_IMMUTABLE - { "nouchg", L"nouchg", UF_IMMUTABLE, 0 }, - { "nouchange", L"nouchange", UF_IMMUTABLE, 0 }, - { "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0 }, + { "nouchg", L"nouchg", UF_IMMUTABLE, 0}, + { "nouchange", L"nouchange", UF_IMMUTABLE, 0}, + { "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0}, #endif #ifdef UF_NODUMP { "nodump", L"nodump", 0, UF_NODUMP}, #endif #if defined(FS_NODUMP_FL) /* 'd' */ { "nodump", L"nodump", 0, FS_NODUMP_FL}, -#elif defined(EXT2_NODUMP_FL) /* 'd' */ +#elif defined(EXT2_NODUMP_FL) { "nodump", L"nodump", 0, EXT2_NODUMP_FL}, #endif #ifdef UF_OPAQUE - { "noopaque", L"noopaque", UF_OPAQUE, 0 }, + { "noopaque", L"noopaque", UF_OPAQUE, 0}, #endif #ifdef UF_NOUNLINK - { "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0 }, - { "nouunlink", L"nouunlink", UF_NOUNLINK, 0 }, + { "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0}, + { "nouunlink", L"nouunlink", UF_NOUNLINK, 0}, #endif #ifdef UF_COMPRESSED - { "nocompressed",L"nocompressed", UF_COMPRESSED, 0 }, + /* Mac OS */ + { "nocompressed", L"nocompressed", UF_COMPRESSED, 0}, #endif #ifdef UF_HIDDEN - { "nohidden", L"nohidden", UF_HIDDEN, 0 }, + { "nohidden", L"nohidden", UF_HIDDEN, 0}, + { "nouhidden", L"nouhidden", UF_HIDDEN, 0}, #endif -#if defined(FS_UNRM_FL) - { "nouunlink", L"nouunlink", FS_UNRM_FL, 0}, -#elif defined(EXT2_UNRM_FL) - { "nouunlink", L"nouunlink", EXT2_UNRM_FL, 0}, +#ifdef UF_OFFLINE + { "nooffline", L"nooffline", UF_OFFLINE, 0}, + { "nouoffline", L"nouoffline", UF_OFFLINE, 0}, #endif - -#if defined(FS_BTREE_FL) - { "nobtree", L"nobtree", FS_BTREE_FL, 0 }, -#elif defined(EXT2_BTREE_FL) - { "nobtree", L"nobtree", EXT2_BTREE_FL, 0 }, +#ifdef UF_READONLY + { "nordonly", L"nordonly", UF_READONLY, 0}, + { "nourdonly", L"nourdonly", UF_READONLY, 0}, + { "noreadonly", L"noreadonly", UF_READONLY, 0}, #endif - -#if defined(FS_ECOMPR_FL) - { "nocomperr", L"nocomperr", FS_ECOMPR_FL, 0 }, -#elif defined(EXT2_ECOMPR_FL) - { "nocomperr", L"nocomperr", EXT2_ECOMPR_FL, 0 }, +#ifdef UF_SPARSE + { "nosparse", L"nosparse", UF_SPARSE, 0}, + { "nousparse", L"nousparse", UF_SPARSE, 0}, #endif - -#if defined(FS_COMPR_FL) /* 'c' */ - { "nocompress", L"nocompress", FS_COMPR_FL, 0 }, -#elif defined(EXT2_COMPR_FL) /* 'c' */ - { "nocompress", L"nocompress", EXT2_COMPR_FL, 0 }, +#ifdef UF_REPARSE + { "noreparse", L"noreparse", UF_REPARSE, 0}, + { "noureparse", L"noureparse", UF_REPARSE, 0}, #endif - -#if defined(FS_NOATIME_FL) /* 'A' */ - { "noatime", L"noatime", 0, FS_NOATIME_FL}, -#elif defined(EXT2_NOATIME_FL) /* 'A' */ - { "noatime", L"noatime", 0, EXT2_NOATIME_FL}, +#ifdef UF_SYSTEM + { "nosystem", L"nosystem", UF_SYSTEM, 0}, + { "nousystem", L"nousystem", UF_SYSTEM, 0}, #endif - -#if defined(FS_DIRTY_FL) - { "nocompdirty",L"nocompdirty", FS_DIRTY_FL, 0}, -#elif defined(EXT2_DIRTY_FL) - { "nocompdirty",L"nocompdirty", EXT2_DIRTY_FL, 0}, +#if defined(FS_UNRM_FL) /* 'u' */ + { "noundel", L"noundel", FS_UNRM_FL, 0}, +#elif defined(EXT2_UNRM_FL) + { "noundel", L"noundel", EXT2_UNRM_FL, 0}, #endif -#if defined(FS_COMPRBLK_FL) -#if defined(FS_NOCOMPR_FL) - { "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, FS_NOCOMPR_FL}, -#else - { "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, 0}, -#endif -#elif defined(EXT2_COMPRBLK_FL) -#if defined(EXT2_NOCOMPR_FL) - { "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL}, -#else - { "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, 0}, +#if defined(FS_COMPR_FL) /* 'c' */ + { "nocompress", L"nocompress", FS_COMPR_FL, 0}, +#elif defined(EXT2_COMPR_FL) + { "nocompress", L"nocompress", EXT2_COMPR_FL, 0}, #endif + +#if defined(FS_NOATIME_FL) /* 'A' */ + { "noatime", L"noatime", 0, FS_NOATIME_FL}, +#elif defined(EXT2_NOATIME_FL) + { "noatime", L"noatime", 0, EXT2_NOATIME_FL}, #endif -#if defined(FS_DIRSYNC_FL) - { "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0}, +#if defined(FS_DIRSYNC_FL) /* 'D' */ + { "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0}, #elif defined(EXT2_DIRSYNC_FL) - { "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0}, -#endif -#if defined(FS_INDEX_FL) - { "nohashidx", L"nohashidx", FS_INDEX_FL, 0}, -#elif defined(EXT2_INDEX_FL) - { "nohashidx", L"nohashidx", EXT2_INDEX_FL, 0}, -#endif -#if defined(FS_IMAGIC_FL) - { "noimagic", L"noimagic", FS_IMAGIC_FL, 0}, -#elif defined(EXT2_IMAGIC_FL) - { "noimagic", L"noimagic", EXT2_IMAGIC_FL, 0}, + { "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0}, #endif -#if defined(FS_JOURNAL_DATA_FL) - { "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0}, +#if defined(FS_JOURNAL_DATA_FL) /* 'j' */ + { "nojournal-data",L"nojournal-data", FS_JOURNAL_DATA_FL, 0}, + { "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0}, #elif defined(EXT3_JOURNAL_DATA_FL) - { "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0}, + { "nojournal-data",L"nojournal-data", EXT3_JOURNAL_DATA_FL, 0}, + { "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0}, #endif -#if defined(FS_SECRM_FL) - { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0}, +#if defined(FS_SECRM_FL) /* 's' */ + { "nosecdel", L"nosecdel", FS_SECRM_FL, 0}, + { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0}, #elif defined(EXT2_SECRM_FL) - { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0}, + { "nosecdel", L"nosecdel", EXT2_SECRM_FL, 0}, + { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0}, #endif -#if defined(FS_SYNC_FL) - { "nosync", L"nosync", FS_SYNC_FL, 0}, +#if defined(FS_SYNC_FL) /* 'S' */ + { "nosync", L"nosync", FS_SYNC_FL, 0}, #elif defined(EXT2_SYNC_FL) - { "nosync", L"nosync", EXT2_SYNC_FL, 0}, + { "nosync", L"nosync", EXT2_SYNC_FL, 0}, #endif -#if defined(FS_NOTAIL_FL) - { "notail", L"notail", 0, FS_NOTAIL_FL}, +#if defined(FS_NOTAIL_FL) /* 't' */ + { "notail", L"notail", 0, FS_NOTAIL_FL}, #elif defined(EXT2_NOTAIL_FL) - { "notail", L"notail", 0, EXT2_NOTAIL_FL}, + { "notail", L"notail", 0, EXT2_NOTAIL_FL}, #endif -#if defined(FS_TOPDIR_FL) - { "notopdir", L"notopdir", FS_TOPDIR_FL, 0}, +#if defined(FS_TOPDIR_FL) /* 'T' */ + { "notopdir", L"notopdir", FS_TOPDIR_FL, 0}, #elif defined(EXT2_TOPDIR_FL) - { "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0}, -#endif -#ifdef FS_ENCRYPT_FL - { "noencrypt", L"noencrypt", FS_ENCRYPT_FL, 0}, -#endif -#ifdef FS_HUGE_FILE_FL - { "nohugefile", L"nohugefile", FS_HUGE_FILE_FL, 0}, -#endif -#ifdef FS_EXTENT_FL - { "noextent", L"noextent", FS_EXTENT_FL, 0}, -#endif -#ifdef FS_EA_INODE_FL - { "noeainode", L"noeainode", FS_EA_INODE_FL, 0}, -#endif -#ifdef FS_EOFBLOCKS_FL - { "noeofblocks",L"noeofblocks", FS_EOFBLOCKS_FL, 0}, -#endif -#ifdef FS_NOCOW_FL - { "nocow", L"nocow", FS_NOCOW_FL, 0}, -#endif -#ifdef FS_INLINE_DATA_FL - { "noinlinedata",L"noinlinedata", FS_INLINE_DATA_FL, 0}, + { "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0}, #endif -#ifdef FS_PROJINHERIT_FL - { "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0}, +#ifdef FS_NOCOW_FL /* 'C' */ + { "nocow", L"nocow", 0, FS_NOCOW_FL}, #endif -#if defined(FS_RESERVED_FL) - { "noreserved", L"noreserved", FS_RESERVED_FL, 0}, -#elif defined(EXT2_RESERVED_FL) - { "noreserved", L"noreserved", EXT2_RESERVED_FL, 0}, +#ifdef FS_PROJINHERIT_FL /* 'P' */ + { "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0}, #endif - { NULL, NULL, 0, 0 } + { NULL, NULL, 0, 0} }; /* diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c index 1786cff38453..7b6102e5eecf 100644 --- a/libarchive/archive_read_disk_entry_from_file.c +++ b/libarchive/archive_read_disk_entry_from_file.c @@ -163,6 +163,9 @@ archive_read_disk_entry_from_file(struct archive *_a, int initial_fd = fd; int r, r1; + archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY, + "archive_read_disk_entry_from_file"); + archive_clear_error(_a); path = archive_entry_sourcepath(entry); if (path == NULL) diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c index 22462a6e18da..159c3b61f5ff 100644 --- a/libarchive/archive_read_support_format_rar5.c +++ b/libarchive/archive_read_support_format_rar5.c @@ -517,15 +517,16 @@ static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt, const uint32_t file_size = 0x1000000; ssize_t i; + const int mask = (int)rar->cstate.window_mask; circular_memcpy(rar->cstate.filtered_buf, rar->cstate.window_buf, - rar->cstate.window_mask, + mask, rar->cstate.solid_offset + flt->block_start, rar->cstate.solid_offset + flt->block_start + flt->block_length); for(i = 0; i < flt->block_length - 4;) { uint8_t b = rar->cstate.window_buf[(rar->cstate.solid_offset + - flt->block_start + i++) & rar->cstate.window_mask]; + flt->block_start + i++) & mask]; /* 0xE8 = x86's call (function call) * 0xE9 = x86's jmp (unconditional jump) */ @@ -534,17 +535,17 @@ static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt, uint32_t addr; uint32_t offset = (i + flt->block_start) % file_size; - addr = read_filter_data(rar, (rar->cstate.solid_offset + + addr = read_filter_data(rar, (uint32_t)(rar->cstate.solid_offset + flt->block_start + i) & rar->cstate.window_mask); if(addr & 0x80000000) { if(((addr + offset) & 0x80000000) == 0) { - write_filter_data(rar, i, addr + file_size); + write_filter_data(rar, (uint32_t)i, addr + file_size); } } else { if((addr - file_size) & 0x80000000) { uint32_t naddr = addr - offset; - write_filter_data(rar, i, naddr); + write_filter_data(rar, (uint32_t)i, naddr); } } @@ -558,11 +559,11 @@ static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt, static int run_arm_filter(struct rar5* rar, struct filter_info* flt) { ssize_t i = 0; uint32_t offset; - const int mask = rar->cstate.window_mask; + const int mask = (int)rar->cstate.window_mask; circular_memcpy(rar->cstate.filtered_buf, rar->cstate.window_buf, - rar->cstate.window_mask, + mask, rar->cstate.solid_offset + flt->block_start, rar->cstate.solid_offset + flt->block_start + flt->block_length); @@ -577,7 +578,7 @@ static int run_arm_filter(struct rar5* rar, struct filter_info* flt) { offset -= (uint32_t) ((i + flt->block_start) / 4); offset = (offset & 0x00ffffff) | 0xeb000000; - write_filter_data(rar, i, offset); + write_filter_data(rar, (uint32_t)i, offset); } } @@ -643,7 +644,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) { static void push_data(struct archive_read* a, struct rar5* rar, const uint8_t* buf, int64_t idx_begin, int64_t idx_end) { - const int wmask = rar->cstate.window_mask; + const int wmask = (int)rar->cstate.window_mask; const ssize_t solid_write_ptr = (rar->cstate.solid_offset + rar->cstate.last_write_ptr) & wmask; @@ -1716,8 +1717,8 @@ static int process_base_block(struct archive_read* a, rar->generic.split_after = (header_flags & HFL_SPLIT_AFTER) > 0; rar->generic.split_before = (header_flags & HFL_SPLIT_BEFORE) > 0; - rar->generic.size = hdr_size; - rar->generic.last_header_id = header_id; + rar->generic.size = (int)hdr_size; + rar->generic.last_header_id = (int)header_id; rar->main.endarc = 0; /* Those are possible header ids in RARv5. */ @@ -1933,7 +1934,7 @@ static int create_decode_tables(uint8_t* bit_length, } } - quick_data_size = 1 << table->quick_bits; + quick_data_size = (int64_t)1 << table->quick_bits; cur_len = 1; for(code = 0; code < quick_data_size; code++) { int bit_field = code << (16 - table->quick_bits); @@ -2364,7 +2365,7 @@ static int decode_code_length(struct rar5* rar, const uint8_t* p, static int copy_string(struct archive_read* a, int len, int dist) { struct rar5* rar = get_context(a); - const int cmask = rar->cstate.window_mask; + const int cmask = (int)rar->cstate.window_mask; const int64_t write_ptr = rar->cstate.write_ptr + rar->cstate.solid_offset; int i; @@ -2390,7 +2391,7 @@ static int do_uncompress_block(struct archive_read* a, const uint8_t* p) { uint16_t num; int ret; - const int cmask = rar->cstate.window_mask; + const int cmask = (int)rar->cstate.window_mask; const struct compressed_block_header* hdr = &rar->last_block_hdr; const uint8_t bit_size = 1 + bf_bit_size(hdr); diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c index 737a25eb1d06..677c43709548 100644 --- a/libarchive/archive_read_support_format_zip.c +++ b/libarchive/archive_read_support_format_zip.c @@ -194,6 +194,7 @@ struct zip { ssize_t zipx_ppmd_read_compressed; CPpmd8 ppmd8; char ppmd8_valid; + char ppmd8_stream_failed; struct archive_string_conv *sconv; struct archive_string_conv *sconv_default; @@ -254,9 +255,15 @@ ppmd_read(void* p) { /* Get the handle to current decompression context. */ struct archive_read *a = ((IByteIn*)p)->a; struct zip *zip = (struct zip*) a->format->data; + ssize_t bytes_avail = 0; /* Fetch next byte. */ - const uint8_t* data = __archive_read_ahead(a, 1, NULL); + const uint8_t* data = __archive_read_ahead(a, 1, &bytes_avail); + if(bytes_avail < 1) { + zip->ppmd8_stream_failed = 1; + return 0; + } + __archive_read_consume(a, 1); /* Increment the counter. */ @@ -1750,6 +1757,7 @@ zipx_ppmd8_init(struct archive_read *a, struct zip *zip) /* Create a new decompression context. */ __archive_ppmd8_functions.Ppmd8_Construct(&zip->ppmd8); + zip->ppmd8_stream_failed = 0; /* Setup function pointers required by Ppmd8 decompressor. The * 'ppmd_read' function will feed new bytes to the decompressor, @@ -1869,6 +1877,14 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff, break; } + /* This field is set by ppmd_read() when there was no more data + * to be read. */ + if(zip->ppmd8_stream_failed) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Truncated PPMd8 file body"); + return (ARCHIVE_FATAL); + } + zip->uncompressed_buffer[consumed_bytes] = (uint8_t) sym; ++consumed_bytes; } while(consumed_bytes < zip->uncompressed_buffer_size); @@ -1902,7 +1918,7 @@ zipx_bzip2_init(struct archive_read *a, struct zip *zip) { int r; - /* Deallocate already existing BZ2 decompression context if it + /* Deallocate already existing BZ2 decompression context if it * exists. */ if(zip->bzstream_valid) { BZ2_bzDecompressEnd(&zip->bzstream); @@ -1968,6 +1984,15 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff, } in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail); + if(in_bytes < 1) { + /* libbz2 doesn't complain when caller feeds avail_in == 0. It will + * actually return success in this case, which is undesirable. This is + * why we need to make this check manually. */ + + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Truncated bzip2 file body"); + return (ARCHIVE_FATAL); + } /* Setup buffer boundaries. */ zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff; diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c index 554533ecb91b..76a1624043f8 100644 --- a/libarchive/archive_string.c +++ b/libarchive/archive_string.c @@ -1512,8 +1512,10 @@ get_current_codepage(void) p = strrchr(locale, '.'); if (p == NULL) return (GetACP()); + if (strcmp(p+1, "utf8") == 0) + return CP_UTF8; cp = my_atoi(p+1); - if (cp <= 0) + if ((int)cp <= 0) return (GetACP()); return (cp); } @@ -4050,6 +4052,7 @@ archive_mstring_copy_utf8(struct archive_mstring *aes, const char *utf8) { if (utf8 == NULL) { aes->aes_set = 0; + return (0); } aes->aes_set = AES_SET_UTF8; archive_string_empty(&(aes->aes_mbs)); @@ -4064,6 +4067,7 @@ archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs, { if (wcs == NULL) { aes->aes_set = 0; + return (0); } aes->aes_set = AES_SET_WCS; /* Only WCS form set. */ archive_string_empty(&(aes->aes_mbs)); diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c index 3ed281df23f3..ed15451762bf 100644 --- a/libarchive/archive_write_disk_posix.c +++ b/libarchive/archive_write_disk_posix.c @@ -2588,8 +2588,11 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, */ restore_pwd = open(".", O_RDONLY | O_BINARY | O_CLOEXEC); __archive_ensure_cloexec_flag(restore_pwd); - if (restore_pwd < 0) + if (restore_pwd < 0) { + fsobj_error(a_eno, a_estr, errno, + "Could not open ", path); return (ARCHIVE_FATAL); + } head = path; tail = path; last = 0; @@ -3128,12 +3131,14 @@ create_dir(struct archive_write_disk *a, char *path) static int set_ownership(struct archive_write_disk *a) { -#ifndef __CYGWIN__ -/* unfortunately, on win32 there is no 'root' user with uid 0, - so we just have to try the chown and see if it works */ - - /* If we know we can't change it, don't bother trying. */ - if (a->user_uid != 0 && a->user_uid != a->uid) { +#if !defined(__CYGWIN__) && !defined(__linux__) +/* + * On Linux, a process may have the CAP_CHOWN capability. + * On Windows there is no 'root' user with uid 0. + * Elsewhere we can skip calling chown if we are not root and the desired + * user id does not match the current user. + */ + if (a->user_uid != 0 && a->user_uid != a->uid) { archive_set_error(&a->archive, errno, "Can't set UID=%jd", (intmax_t)a->uid); return (ARCHIVE_WARN); @@ -3500,9 +3505,7 @@ set_fflags(struct archive_write_disk *a) struct fixup_entry *le; unsigned long set, clear; int r; - int critical_flags; mode_t mode = archive_entry_mode(a->entry); - /* * Make 'critical_flags' hold all file flags that can't be * immediately restored. For example, on BSD systems, @@ -3518,33 +3521,33 @@ set_fflags(struct archive_write_disk *a) * other programs that might try to muck with files as they're * being restored. */ - /* Hopefully, the compiler will optimize this mess into a constant. */ - critical_flags = 0; + const int critical_flags = 0 #ifdef SF_IMMUTABLE - critical_flags |= SF_IMMUTABLE; + | SF_IMMUTABLE #endif #ifdef UF_IMMUTABLE - critical_flags |= UF_IMMUTABLE; + | UF_IMMUTABLE #endif #ifdef SF_APPEND - critical_flags |= SF_APPEND; + | SF_APPEND #endif #ifdef UF_APPEND - critical_flags |= UF_APPEND; + | UF_APPEND #endif #if defined(FS_APPEND_FL) - critical_flags |= FS_APPEND_FL; + | FS_APPEND_FL #elif defined(EXT2_APPEND_FL) - critical_flags |= EXT2_APPEND_FL; + | EXT2_APPEND_FL #endif #if defined(FS_IMMUTABLE_FL) - critical_flags |= FS_IMMUTABLE_FL; + | FS_IMMUTABLE_FL #elif defined(EXT2_IMMUTABLE_FL) - critical_flags |= EXT2_IMMUTABLE_FL; + | EXT2_IMMUTABLE_FL #endif #ifdef FS_JOURNAL_DATA_FL - critical_flags |= FS_JOURNAL_DATA_FL; + | FS_JOURNAL_DATA_FL #endif + ; if (a->todo & TODO_FFLAGS) { archive_entry_fflags(a->entry, &set, &clear); @@ -3575,29 +3578,27 @@ set_fflags(struct archive_write_disk *a) static int clear_nochange_fflags(struct archive_write_disk *a) { - int nochange_flags; mode_t mode = archive_entry_mode(a->entry); - - /* Hopefully, the compiler will optimize this mess into a constant. */ - nochange_flags = 0; + const int nochange_flags = 0 #ifdef SF_IMMUTABLE - nochange_flags |= SF_IMMUTABLE; + | SF_IMMUTABLE #endif #ifdef UF_IMMUTABLE - nochange_flags |= UF_IMMUTABLE; + | UF_IMMUTABLE #endif #ifdef SF_APPEND - nochange_flags |= SF_APPEND; + | SF_APPEND #endif #ifdef UF_APPEND - nochange_flags |= UF_APPEND; + | UF_APPEND #endif #ifdef EXT2_APPEND_FL - nochange_flags |= EXT2_APPEND_FL; + | EXT2_APPEND_FL #endif #ifdef EXT2_IMMUTABLE_FL - nochange_flags |= EXT2_IMMUTABLE_FL; + | EXT2_IMMUTABLE_FL #endif + ; return (set_fflags_platform(a, a->fd, a->name, mode, 0, nochange_flags)); @@ -3613,8 +3614,22 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name, mode_t mode, unsigned long set, unsigned long clear) { int r; - + const int sf_mask = 0 +#ifdef SF_APPEND + | SF_APPEND +#endif +#ifdef SF_ARCHIVED + | SF_ARCHIVED +#endif +#ifdef SF_IMMUTABLE + | SF_IMMUTABLE +#endif +#ifdef SF_NOUNLINK + | SF_NOUNLINK +#endif + ; (void)mode; /* UNUSED */ + if (set == 0 && clear == 0) return (ARCHIVE_OK); @@ -3629,6 +3644,12 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name, a->st.st_flags &= ~clear; a->st.st_flags |= set; + + /* Only super-user may change SF_* flags */ + + if (a->user_uid != 0) + a->st.st_flags &= ~sf_mask; + #ifdef HAVE_FCHFLAGS /* If platform has fchflags() and we were given an fd, use it. */ if (fd >= 0 && fchflags(fd, a->st.st_flags) == 0) @@ -3670,22 +3691,6 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name, int ret; int myfd = fd; int newflags, oldflags; - int sf_mask = 0; - - if (set == 0 && clear == 0) - return (ARCHIVE_OK); - /* Only regular files and dirs can have flags. */ - if (!S_ISREG(mode) && !S_ISDIR(mode)) - return (ARCHIVE_OK); - - /* If we weren't given an fd, open it ourselves. */ - if (myfd < 0) { - myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY | O_CLOEXEC); - __archive_ensure_cloexec_flag(myfd); - } - if (myfd < 0) - return (ARCHIVE_OK); - /* * Linux has no define for the flags that are only settable by * the root user. This code may seem a little complex, but @@ -3693,19 +3698,36 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name, * defines. (?) The code below degrades reasonably gracefully * if sf_mask is incomplete. */ + const int sf_mask = 0 #if defined(FS_IMMUTABLE_FL) - sf_mask |= FS_IMMUTABLE_FL; + | FS_IMMUTABLE_FL #elif defined(EXT2_IMMUTABLE_FL) - sf_mask |= EXT2_IMMUTABLE_FL; + | EXT2_IMMUTABLE_FL #endif #if defined(FS_APPEND_FL) - sf_mask |= FS_APPEND_FL; + | FS_APPEND_FL #elif defined(EXT2_APPEND_FL) - sf_mask |= EXT2_APPEND_FL; + | EXT2_APPEND_FL #endif #if defined(FS_JOURNAL_DATA_FL) - sf_mask |= FS_JOURNAL_DATA_FL; + | FS_JOURNAL_DATA_FL #endif + ; + + if (set == 0 && clear == 0) + return (ARCHIVE_OK); + /* Only regular files and dirs can have flags. */ + if (!S_ISREG(mode) && !S_ISDIR(mode)) + return (ARCHIVE_OK); + + /* If we weren't given an fd, open it ourselves. */ + if (myfd < 0) { + myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY | O_CLOEXEC); + __archive_ensure_cloexec_flag(myfd); + } + if (myfd < 0) + return (ARCHIVE_OK); + /* * XXX As above, this would be way simpler if we didn't have * to read the current flags from disk. XXX diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c index 135dd97eacac..975555f2e732 100644 --- a/libarchive/archive_write_disk_windows.c +++ b/libarchive/archive_write_disk_windows.c @@ -474,6 +474,11 @@ permissive_name_w(struct archive_write_disk *a) { archive_wstrncpy(&(a->_name_data), wsp, l); } + else if (l > 2 && wsp[0] == L'\\' && wsp[1] == L'\\' && wsp[2] != L'\\') + { + archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8); + archive_wstrncat(&(a->_name_data), wsp+2, l-2); + } else { archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4); diff --git a/libarchive/archive_write_set_format_7zip.c b/libarchive/archive_write_set_format_7zip.c index f63a2266a85e..92a87f74e625 100644 --- a/libarchive/archive_write_set_format_7zip.c +++ b/libarchive/archive_write_set_format_7zip.c @@ -439,7 +439,8 @@ _7z_write_header(struct archive_write *a, struct archive_entry *entry) r = file_new(a, entry, &file); if (r < ARCHIVE_WARN) { - file_free(file); + if (file != NULL) + file_free(file); return (r); } if (file->size == 0 && file->dir) { diff --git a/libarchive/test/test_entry.c b/libarchive/test/test_entry.c index 0ccc9e8fb355..a0a2607a156c 100644 --- a/libarchive/test/test_entry.c +++ b/libarchive/test/test_entry.c @@ -336,7 +336,7 @@ DEFINE_TEST(test_entry) /* Converting fflags bitmap to string is currently system-dependent. */ /* TODO: Make this system-independent. */ assertEqualString(archive_entry_fflags_text(e), - "uappnd,nouchg,nodump,noopaque,uunlnk"); + "uappnd,nouchg,nodump,noopaque,uunlnk,nosystem"); /* Test archive_entry_copy_fflags_text_w() */ archive_entry_copy_fflags_text_w(e, L" ,nouappnd, nouchg, dump,uunlnk"); archive_entry_fflags(e, &set, &clear); diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c index 7f2f32df48c5..0be9c45a5d49 100644 --- a/libarchive/test/test_read_format_rar5.c +++ b/libarchive/test/test_read_format_rar5.c @@ -96,7 +96,7 @@ int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) { int ret = 1; uint32_t computed_crc; - fsize = archive_entry_size(ae); + fsize = (la_ssize_t) archive_entry_size(ae); buf = malloc(fsize); if(buf == NULL) return 1; @@ -110,13 +110,13 @@ int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) { computed_crc = crc32(0, buf, fsize); assertEqualInt(computed_crc, crc); ret = 0; - + fn_exit: free(buf); return ret; } -DEFINE_TEST(test_read_format_rar5_stored) +DEFINE_TEST(test_read_format_rar5_stored) { const char helloworld_txt[] = "hello libarchive test suite!\n"; la_ssize_t file_size = sizeof(helloworld_txt) - 1; @@ -143,7 +143,7 @@ DEFINE_TEST(test_read_format_rar5_stored) DEFINE_TEST(test_read_format_rar5_compressed) { const int DATA_SIZE = 1200; - uint8_t buff[DATA_SIZE]; + uint8_t buff[1200]; PROLOGUE("test_read_format_rar5_compressed.rar"); @@ -161,7 +161,7 @@ DEFINE_TEST(test_read_format_rar5_compressed) DEFINE_TEST(test_read_format_rar5_multiple_files) { const int DATA_SIZE = 4096; - uint8_t buff[DATA_SIZE]; + uint8_t buff[4096]; PROLOGUE("test_read_format_rar5_multiple_files.rar"); @@ -173,7 +173,7 @@ DEFINE_TEST(test_read_format_rar5_multiple_files) assertEqualInt(DATA_SIZE, archive_entry_size(ae)); assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); assertA(verify_data(buff, 1, DATA_SIZE)); - + assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test2.bin", archive_entry_pathname(ae)); assertEqualInt(DATA_SIZE, archive_entry_size(ae)); @@ -207,7 +207,7 @@ DEFINE_TEST(test_read_format_rar5_multiple_files) DEFINE_TEST(test_read_format_rar5_multiple_files_solid) { const int DATA_SIZE = 4096; - uint8_t buff[DATA_SIZE]; + uint8_t buff[4096]; PROLOGUE("test_read_format_rar5_multiple_files_solid.rar"); @@ -216,7 +216,7 @@ DEFINE_TEST(test_read_format_rar5_multiple_files_solid) assertEqualInt(DATA_SIZE, archive_entry_size(ae)); assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); assertA(verify_data(buff, 1, DATA_SIZE)); - + assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test2.bin", archive_entry_pathname(ae)); assertEqualInt(DATA_SIZE, archive_entry_size(ae)); @@ -309,7 +309,7 @@ DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_second) DEFINE_TEST(test_read_format_rar5_blake2) { const la_ssize_t proper_size = 814; - uint8_t buf[proper_size]; + uint8_t buf[814]; PROLOGUE("test_read_format_rar5_blake2.rar"); assertA(0 == archive_read_next_header(a, &ae)); @@ -334,7 +334,7 @@ DEFINE_TEST(test_read_format_rar5_arm_filter) * test. */ const la_ssize_t proper_size = 90808; - uint8_t buf[proper_size]; + uint8_t buf[90808]; PROLOGUE("test_read_format_rar5_arm.rar"); assertA(0 == archive_read_next_header(a, &ae)); @@ -598,7 +598,7 @@ DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_last) EPILOGUE(); } -DEFINE_TEST(test_read_format_rar5_solid_skip_all) +DEFINE_TEST(test_read_format_rar5_solid_skip_all) { const char* reffile = "test_read_format_rar5_solid.rar"; @@ -623,7 +623,7 @@ DEFINE_TEST(test_read_format_rar5_solid_skip_all) EPILOGUE(); } -DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first) +DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first) { const char* reffile = "test_read_format_rar5_solid.rar"; @@ -649,7 +649,7 @@ DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first) EPILOGUE(); } -DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second) +DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second) { const char* reffile = "test_read_format_rar5_solid.rar"; diff --git a/libarchive/test/test_read_format_xar.c b/libarchive/test/test_read_format_xar.c index 4654f8386efb..1c8524520b39 100644 --- a/libarchive/test/test_read_format_xar.c +++ b/libarchive/test/test_read_format_xar.c @@ -799,7 +799,7 @@ static void verify(unsigned char *d, size_t s, static void verifyB(unsigned char *d, size_t s) { struct archive* a; struct archive_entry *entry = NULL; - la_int64_t buf_size; + size_t buf_size; unsigned char *buf; assert((a = archive_read_new()) != NULL); @@ -826,20 +826,20 @@ static void verifyB(unsigned char *d, size_t s) { // f1, content "onetwothree\n", size 12 bytes assertA(0 == archive_read_next_header(a, &entry)); - buf_size = archive_entry_size(entry); + buf_size = (size_t) archive_entry_size(entry); assertA(buf_size == 12); buf = (unsigned char*) malloc(buf_size); assertA(NULL != buf); - assertA(buf_size == archive_read_data(a, buf, buf_size)); + assertA(buf_size == (size_t) archive_read_data(a, buf, buf_size)); free(buf); // f2, content "fourfivesix\n", size 12 bytes assertA(0 == archive_read_next_header(a, &entry)); - buf_size = archive_entry_size(entry); + buf_size = (size_t) archive_entry_size(entry); assertA(buf_size == 12); buf = (unsigned char*) malloc(buf_size); assertA(NULL != buf); - assertA(buf_size == archive_read_data(a, buf, buf_size)); + assertA(buf_size == (size_t) archive_read_data(a, buf, buf_size)); free(buf); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); diff --git a/libarchive/test/test_read_format_zip.c b/libarchive/test/test_read_format_zip.c index b965299a4f5c..14c5ada81053 100644 --- a/libarchive/test/test_read_format_zip.c +++ b/libarchive/test/test_read_format_zip.c @@ -37,7 +37,7 @@ int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) int ret = 1; uint32_t computed_crc; - fsize = archive_entry_size(ae); + fsize = (la_ssize_t) archive_entry_size(ae); buf = malloc(fsize); if(buf == NULL) return 1; @@ -759,3 +759,67 @@ DEFINE_TEST(test_read_format_zip_xz_multi_blockread) assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); } + +DEFINE_TEST(test_read_format_zip_ppmd8_crash_1) +{ + const char *refname = "test_read_format_zip_ppmd8_crash_2.zipx"; + struct archive *a; + struct archive_entry *ae; + char buf[64]; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 100)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* This file shouldn't be properly decompressed, because it's invalid. + * However, unpacker should return an error during unpacking. Without the + * proper fix, the unpacker was entering an unlimited loop. */ + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 1)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_bz2_hang_on_invalid) +{ + const char *refname = "test_read_format_zip_bz2_hang.zip"; + struct archive *a; + struct archive_entry *ae; + char buf[8]; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + 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)); + + /* The file `refname` is invalid in this case, so this call should fail. + * But it shouldn't crash. */ + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 64)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_ppmd8_crash_2) +{ + const char *refname = "test_read_format_zip_ppmd8_crash_2.zipx"; + struct archive *a; + struct archive_entry *ae; + char buf[64]; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + 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)); + + /* The file `refname` is invalid in this case, so this call should fail. + * But it shouldn't crash. */ + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 64)); + 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_bz2_hang.zip.uu b/libarchive/test/test_read_format_zip_bz2_hang.zip.uu new file mode 100644 index 000000000000..5193a77aee33 --- /dev/null +++ b/libarchive/test/test_read_format_zip_bz2_hang.zip.uu @@ -0,0 +1,5 @@ +begin 644 test_read_format_zip_bz2_hang.zip +M4$L#!)LP,#`,,#`P,#`P,#`P,#`P,#`P,#`$`!P`,#`P,#`P"0`P,#`P,#`P +1,#!U>`L`8(0P,#`P,#`P,#`` +` +end diff --git a/libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu b/libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu new file mode 100644 index 000000000000..fb6050fc086d --- /dev/null +++ b/libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu @@ -0,0 +1,4 @@ +begin 644 test_read_format_zip_ppmd8_crash_1.zipx +K4$L'"(=02P,$\+N.O&*A>*\+."U``$H`````````@``````#````6(0````` +` +end diff --git a/libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu b/libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu new file mode 100644 index 000000000000..58de41258665 --- /dev/null +++ b/libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu @@ -0,0 +1,4 @@ +begin 644 test_read_format_zip_ppmd8_crash_2.zipx +L4$L'"(=02P,$\+N.O&*A>*\+.2U`@$H`````````@``````#```````````` +` +end -- cgit v1.2.3