Update vendor/libarchive to 3.7.4

Security fixes:
 #2135 rar: Fix OOB in rar e8 filter (CVE-2024-26256)
 #2145 zip: Fix out of boundary access

Important bugfixes:
 #2131 7zip: Limit amount of properties
 #2110 bsdtar: Fix error handling around strtol() usages
 #2116 passphrase: Never allow empty passwords
 #2124 rar: Fix "File CRC Error" when extracting specific rar4 archives
 #2123 xar: Avoid infinite link loop
 #2108 zip: Update AppleDouble support for directories
 #2071 zstd: Implement core detection

Obained from:		libarchive
Libarchive commit:	313aa1fa10b657de791e3202c168a6c833bc3543
This commit is contained in:
Martin Matuska 2024-04-26 12:11:59 +02:00
parent a509d68f27
commit d6f77d3cfa
48 changed files with 436 additions and 135 deletions

View file

@ -9,6 +9,8 @@ updates:
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "CI"
groups:
all-actions:
patterns:

View file

@ -12,7 +12,7 @@ jobs:
matrix:
bs: [autotools, cmake]
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- name: Install dependencies
run: ./build/ci/github_actions/macos.sh prepare
- name: Autogen
@ -45,7 +45,7 @@ jobs:
run: ./build/ci/build.sh -a artifact
env:
BS: ${{ matrix.bs }}
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: libarchive-macos-${{ matrix.bs }}-${{ github.sha }}
path: libarchive.tar.xz
@ -57,7 +57,7 @@ jobs:
bs: [autotools, cmake]
crypto: [mbedtls, nettle, openssl]
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- name: Update apt cache
run: sudo apt-get update
- name: Install dependencies
@ -91,14 +91,14 @@ jobs:
run: ./build/ci/build.sh -a artifact
env:
BS: ${{ matrix.bs }}
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: libarchive-ubuntu-${{ matrix.bs }}-${{ matrix.crypto }}-${{ github.sha }}
path: libarchive.tar.xz
Ubuntu-distcheck:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- name: Update package definitions
run: sudo apt-get update
- name: Install dependencies
@ -113,7 +113,7 @@ jobs:
SKIP_OPEN_FD_ERR_TEST: 1
- name: Dist-Artifact
run: ./build/ci/build.sh -a dist-artifact
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: libarchive-${{ github.sha }}
path: libarchive-dist.tar
@ -125,7 +125,7 @@ jobs:
matrix:
be: [mingw-gcc, msvc]
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- name: Install mingw
if: ${{ matrix.be=='mingw-gcc' }}
run: choco install mingw
@ -161,7 +161,7 @@ jobs:
shell: cmd
env:
BE: ${{ matrix.be }}
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: libarchive-windows-${{ matrix.be }}-${{ github.sha }}
path: libarchive.zip

View file

@ -21,7 +21,7 @@ jobs:
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts

View file

@ -26,18 +26,18 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- name: Initialize CodeQL
uses: github/codeql-action/init@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
uses: github/codeql-action/init@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
uses: github/codeql-action/autobuild@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
uses: github/codeql-action/analyze@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
with:
category: "/language:${{ matrix.language }}"

View file

@ -29,7 +29,7 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
with:
persist-credentials: false
@ -52,7 +52,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: SARIF file
path: results.sarif
@ -60,6 +60,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
uses: github/codeql-action/upload-sarif@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2
with:
sarif_file: results.sarif

17
.gitignore vendored
View file

@ -1,13 +1,23 @@
*~
*.o
*.obj
*.exe
*.exp
*.ilk
*.la
*.lib
*.lo
*.recipe
*.sln
*.tlog
*.cmake
*.vcxproj
*.vcxproj.filters
!build/cmake/*.cmake
.deps/
.libs/
bin/
out/
.dirstamp
Makefile
Makefile.in
@ -29,7 +39,13 @@ build/autoconf/ltsugar.m4
build/autoconf/ltversion.m4
build/autoconf/lt~obsolete.m4
build/autoconf/missing
build/build/pkgconfig/libarchive.pc
build/cat/test/list.h
build/cpio/test/list.h
build/libarchive/test/list.h
build/pkgconfig/libarchive.pc
build/tar/test/list.h
build/unzip/test/list.h
cat/test/list.h
config.cache
config.h
@ -47,6 +63,7 @@ CMakeCache.txt
CMakeFiles/
DartConfiguration.tcl
cmake.tmp/
.vs/
.vscode/
doc/html/*.html

View file

@ -34,13 +34,15 @@ IF("${cached_type}" STREQUAL "UNINITIALIZED")
SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Build Type" FORCE)
ENDIF("${cached_type}" STREQUAL "UNINITIALIZED")
# Check the Build Type.
IF(NOT "${CMAKE_BUILD_TYPE}"
MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel|None)\$")
# Convert the CMAKE_BUILD_TYPE to uppercase to perform a case-insensitive comparison.
string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER)
IF(NOT "${CMAKE_BUILD_TYPE_UPPER}"
MATCHES "^(DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL|NONE)\$")
MESSAGE(FATAL_ERROR
"Unknown keyword for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n"
"Acceptable keywords: Debug,Release,RelWithDebInfo,MinSizeRel,None")
ENDIF(NOT "${CMAKE_BUILD_TYPE}"
MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel|None)\$")
"Acceptable keywords: Debug, Release, RelWithDebInfo, MinSizeRel, None")
ENDIF(NOT "${CMAKE_BUILD_TYPE_UPPER}"
MATCHES "^(DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL|NONE)\$")
# On MacOS, prefer MacPorts libraries to system libraries.
# I haven't come up with a compelling argument for this to be conditional.
@ -1495,6 +1497,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S)
CHECK_FUNCTION_EXISTS_GLIBC(strnlen HAVE_STRNLEN)
CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
CHECK_FUNCTION_EXISTS_GLIBC(sysconf HAVE_SYSCONF)
CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT)

View file

@ -528,6 +528,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_format_ustar_filename.c \
libarchive/test/test_read_format_warc.c \
libarchive/test/test_read_format_xar.c \
libarchive/test/test_read_format_xar_doublelink.c \
libarchive/test/test_read_format_zip.c \
libarchive/test/test_read_format_zip_7075_utf8_paths.c \
libarchive/test/test_read_format_zip_comment_stored.c \
@ -932,6 +933,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_warc.warc.uu \
libarchive/test/test_read_format_xar_doublelink.xar.uu \
libarchive/test/test_read_format_zip.zip.uu \
libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \
libarchive/test/test_read_format_zip_7z_deflate.zip.uu \

2
NEWS
View file

@ -1,3 +1,5 @@
Apr 26, 2024: libarchive 3.7.4 released
Apr 08, 2024: libarchive 3.7.3 released
Sep 12, 2023: libarchive 3.7.2 released

View file

@ -201,7 +201,7 @@ questions we are asked about libarchive:
In case other thread calls the same function in parallel, it might
get interrupted by it and cause the executable to use umask=0 for the
remaining execution.
This will then lead to implicitely created directories to have 777
This will then lead to implicitly created directories to have 777
permissions without sticky bit.
* In particular, libarchive's modules to read or write a directory

View file

@ -18,6 +18,7 @@ then
xz \
lz4 \
zstd \
libxml2 \
openssl
do
brew list $pkg > /dev/null && brew upgrade $pkg || brew install $pkg

View file

@ -1094,6 +1094,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `symlink' function. */
#cmakedefine HAVE_SYMLINK 1
/* Define to 1 if you have the `sysconf' function. */
#cmakedefine HAVE_SYSCONF 1
/* Define to 1 if you have the <sys/acl.h> header file. */
#cmakedefine HAVE_SYS_ACL_H 1

View file

@ -1 +1 @@
3007003
3007004

View file

@ -114,12 +114,18 @@ bsdcat_getopt(struct bsdcat *bsdcat)
enum { state_start = 0, state_old_tar, state_next_word,
state_short, state_long };
const struct bsdcat_option *popt, *match = NULL, *match2 = NULL;
const char *p, *long_prefix = "--";
const struct bsdcat_option *popt, *match, *match2;
const char *p, *long_prefix;
size_t optlength;
int opt = '?';
int required = 0;
int opt;
int required;
again:
match = NULL;
match2 = NULL;
long_prefix = "--";
opt = '?';
required = 0;
bsdcat->argument = NULL;
/* First time through, initialize everything. */
@ -172,7 +178,7 @@ bsdcat_getopt(struct bsdcat *bsdcat)
if (opt == '\0') {
/* End of this group; recurse to get next option. */
bsdcat->getopt_state = state_next_word;
return bsdcat_getopt(bsdcat);
goto again;
}
/* Does this option take an argument? */

View file

@ -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.7.3])
m4_define([LIBARCHIVE_VERSION_N],[3007003])
m4_define([LIBARCHIVE_VERSION_S],[3.7.4])
m4_define([LIBARCHIVE_VERSION_N],[3007004])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
@ -662,7 +662,7 @@ AC_LINK_IFELSE(
DEAD_CODE_REMOVAL="";])
LDFLAGS=$save_LDFLAGS
if test "$DEAD_CODE_REMOVAL" == ""; then
if test "$DEAD_CODE_REMOVAL" = ""; then
# Macos linkers have a -dead_strip flag, which is similar to --gc-sections.
save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,-dead_strip"
@ -804,6 +804,7 @@ AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawnp readlink readlinkat])
AC_CHECK_FUNCS([readpassphrase])
AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strnlen strrchr symlink])
AC_CHECK_FUNCS([sysconf])
AC_CHECK_FUNCS([timegm tzset unlinkat unsetenv utime utimensat utimes vfork])
AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy wmemmove])
AC_CHECK_FUNCS([_fseeki64 _get_timezone])

View file

@ -114,12 +114,18 @@ cpio_getopt(struct cpio *cpio)
static int state = state_start;
static char *opt_word;
const struct option *popt, *match = NULL, *match2 = NULL;
const char *p, *long_prefix = "--";
const struct option *popt, *match, *match2;
const char *p, *long_prefix;
size_t optlength;
int opt = '?';
int required = 0;
int opt;
int required;
again:
match = NULL;
match2 = NULL;
long_prefix = "--";
opt = '?';
required = 0;
cpio->argument = NULL;
/* First time through, initialize everything. */
@ -169,7 +175,7 @@ cpio_getopt(struct cpio *cpio)
if (opt == '\0') {
/* End of this group; recurse to get next option. */
state = state_next_word;
return cpio_getopt(cpio);
goto again;
}
/* Does this option take an argument? */

View file

@ -34,7 +34,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3007003
#define ARCHIVE_VERSION_NUMBER 3007004
#include <sys/stat.h>
#include <stddef.h> /* 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.7.3"
#define ARCHIVE_VERSION_ONLY_STRING "3.7.4"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@ -895,7 +895,7 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
const char *opts);
/*
* Set a encryption passphrase.
* Set an encryption passphrase.
*/
__LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p);
__LA_DECL int archive_write_set_passphrase_callback(struct archive *,

View file

@ -28,7 +28,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3007003
#define ARCHIVE_VERSION_NUMBER 3007004
/*
* Note: archive_entry.h is for use outside of libarchive; the

View file

@ -383,7 +383,7 @@ Prefix each default ACL entry with the word
The mask and other ACLs don not contain a double colon.
.El
.Pp
The following flags are effecive only on NFSv4 ACL:
The following flags are effective only on NFSv4 ACL:
.Bl -tag -offset indent -compact -width ARCHIV
.It Dv ARCHIVE_ENTRY_ACL_STYLE_COMPACT
Do not output minus characters for unset permissions and flags in NFSv4 ACL

View file

@ -288,11 +288,11 @@ calls. If matched based on calls to
.Tn archive_match_time_excluded ,
or
.Tn archive_match_owner_excluded ,
then the callback function specified by the _excluded_func parameter will execute. This function will recieve data provided to the fourth parameter, void *_client_data.
then the callback function specified by the _excluded_func parameter will execute. This function will receive data provided to the fourth parameter, void *_client_data.
.It Fn archive_read_disk_set_metadata_filter_callback
Allows the caller to set a callback function during calls to
.Xr archive_read_header 3
to filter out metadata for each entry. The callback function recieves the
to filter out metadata for each entry. The callback function receives the
.Tn struct archive
object, void* custom filter data, and the
.Tn struct archive_entry .

View file

@ -2037,6 +2037,8 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
if (parse_7zip_uint64(
a, &(f->coders[i].propertiesSize)) < 0)
return (-1);
if (UMAX_ENTRY < f->coders[i].propertiesSize)
return (-1);
if ((p = header_bytes(
a, (size_t)f->coders[i].propertiesSize)) == NULL)
return (-1);

View file

@ -67,7 +67,7 @@ archive_read_support_format_all(struct archive *a)
* increase the chance that a high bid from someone else will
* make it unnecessary for these to do anything at all.
*/
/* These three have potentially large look-ahead. */
/* These have potentially large look-ahead. */
archive_read_support_format_7zip(a);
archive_read_support_format_cab(a);
archive_read_support_format_rar(a);

View file

@ -270,7 +270,7 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
}
if (ar->strtab != NULL) {
archive_set_error(&a->archive, EINVAL,
"More than one string tables exist");
"More than one string table exists");
return (ARCHIVE_FATAL);
}
@ -515,7 +515,7 @@ archive_read_format_ar_read_data(struct archive_read *a,
if (ar->entry_padding) {
if (skipped >= 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Truncated ar archive- failed consuming padding");
"Truncated ar archive - failed consuming padding");
}
return (ARCHIVE_FATAL);
}

View file

@ -1693,7 +1693,7 @@ archive_read_format_lha_cleanup(struct archive_read *a)
* example.
* 1. a symbolic-name is 'aaa/bb/cc'
* 2. a filename is 'xxx/bbb'
* then a archived pathname is 'xxx/bbb|aaa/bb/cc'
* then an archived pathname is 'xxx/bbb|aaa/bb/cc'
*/
static int
lha_parse_linkname(struct archive_wstring *linkname,
@ -2385,7 +2385,7 @@ lzh_decode_blocks(struct lzh_stream *strm, int last)
return (100);
}
/* lzh_br_read_ahead() always try to fill the
/* lzh_br_read_ahead() always tries to fill the
* cache buffer up. In specific situation we
* are close to the end of the data, the cache
* buffer will not be full and thus we have to

View file

@ -416,8 +416,8 @@ next_line(struct archive_read *a,
}
/*
* Compare characters with a mtree keyword.
* Returns the length of a mtree keyword if matched.
* Compare characters with an mtree keyword.
* Returns the length of an mtree keyword if matched.
* Returns 0 if not matched.
*/
static int
@ -515,7 +515,7 @@ bid_keyword(const char *p, ssize_t len)
/*
* Test whether there is a set of mtree keywords.
* Returns the number of keyword.
* Returns the number of keywords.
* Returns -1 if we got incorrect sequence.
* This function expects a set of "<space characters>keyword=value".
* When "unset" is specified, expects a set of "<space characters>keyword".
@ -760,7 +760,7 @@ detect_form(struct archive_read *a, int *is_form_d)
multiline = 1;
else {
/* We've got plenty of correct lines
* to assume that this file is a mtree
* to assume that this file is an mtree
* format. */
if (++entry_cnt >= MAX_BID_ENTRY)
break;

View file

@ -2176,6 +2176,19 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
{
start = rar->offset;
end = start + rar->dictionary_size;
/* We don't want to overflow the window and overwrite data that we write
* at 'start'. Therefore, reduce the end length by the maximum match size,
* which is 260 bytes. You can compute this maximum by looking at the
* definition of 'expand', in particular when 'symbol >= 271'. */
/* NOTE: It's possible for 'dictionary_size' to be less than this 260
* value, however that will only be the case when 'unp_size' is small,
* which should only happen when the entry size is small and there's no
* risk of overflowing the buffer */
if (rar->dictionary_size > 260) {
end -= 260;
}
if (rar->filters.filterstart < end) {
end = rar->filters.filterstart;
}
@ -3615,7 +3628,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
uint32_t filesize = 0x1000000;
uint32_t i;
if (length > PROGRAM_WORK_SIZE || length < 4)
if (length > PROGRAM_WORK_SIZE || length <= 4)
return 0;
for (i = 0; i <= length - 5; i++)

View file

@ -215,6 +215,7 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
const char *buf;
ssize_t nrd;
const char *eoh;
char *tmp;
/* for the file name, saves some strndup()'ing */
warc_string_t fnam;
/* warc record type, not that we really use it a lot */
@ -321,7 +322,14 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
* malloc()+free() roundtrip */
if (fnam.len + 1U > w->pool.len) {
w->pool.len = ((fnam.len + 64U) / 64U) * 64U;
w->pool.str = realloc(w->pool.str, w->pool.len);
tmp = realloc(w->pool.str, w->pool.len);
if (tmp == NULL) {
archive_set_error(
&a->archive, ENOMEM,
"Out of memory");
return (ARCHIVE_FATAL);
}
w->pool.str = tmp;
}
memcpy(w->pool.str, fnam.str, fnam.len);
w->pool.str[fnam.len] = '\0';

View file

@ -2055,6 +2055,11 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
attr = attr->next) {
if (strcmp(attr->name, "link") != 0)
continue;
if (xar->file->hdnext != NULL || xar->file->link != 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"File with multiple link targets");
return (ARCHIVE_FATAL);
}
if (strcmp(attr->value, "original") == 0) {
xar->file->hdnext = xar->hdlink_orgs;
xar->hdlink_orgs = xar->file;

View file

@ -1393,7 +1393,7 @@ check_authentication_code(struct archive_read *a, const void *_p)
* [CRC32] [compressed low] [compressed high] [uncompressed low] [uncompressed high] [other PK marker]
* ```
* Since the 32-bit and 64-bit compressed sizes both match, the
* actualy size must fit in 32 bits, which implies the high-order
* actual size must fit in 32 bits, which implies the high-order
* word of the compressed size is zero. So we know the uncompressed
* low word is zero, which again implies that if we accept the shorter
* format, there will not be a valid PK marker following it.
@ -4083,6 +4083,17 @@ slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
} else {
/* Generate resource fork name to find its
* resource file at zip->tree_rsrc. */
/* If this is an entry ending with slash,
* make the resource for name slash-less
* as the actual resource fork doesn't end with '/'.
*/
size_t tmp_length = filename_length;
if (tmp_length > 0 && name[tmp_length - 1] == '/') {
tmp_length--;
r = rsrc_basename(name, tmp_length);
}
archive_strcpy(&(zip_entry->rsrcname),
"__MACOSX/");
archive_strncat(&(zip_entry->rsrcname),
@ -4090,7 +4101,7 @@ slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
archive_strcat(&(zip_entry->rsrcname), "._");
archive_strncat(&(zip_entry->rsrcname),
name + (r - name),
filename_length - (r - name));
tmp_length - (r - name));
/* Register an entry to RB tree to sort it by
* file offset. */
__archive_rb_tree_insert_node(&zip->tree,

View file

@ -255,10 +255,9 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
#endif
fd = -1;
ws = NULL;
archive_string_init(&temp_name);
if (template == NULL) {
archive_string_init(&temp_name);
/* Get a temporary directory. */
if (tmpdir == NULL) {
size_t l;

View file

@ -29,6 +29,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
@ -38,6 +41,9 @@
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ZSTD_H
#include <zstd.h>
#endif
@ -190,6 +196,7 @@ string_to_number(const char *string, intmax_t *numberp)
return (ARCHIVE_OK);
}
#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
static int
string_to_size(const char *string, size_t *numberp)
{
@ -224,6 +231,7 @@ string_to_size(const char *string, size_t *numberp)
*numberp = (size_t)(number << shift);
return (ARCHIVE_OK);
}
#endif
/*
* Set write options.
@ -264,7 +272,20 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
if (string_to_number(value, &threads) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
if (threads < 0) {
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
if (threads == 0) {
threads = sysconf(_SC_NPROCESSORS_ONLN);
}
#elif !defined(__CYGWIN__) && defined(_WIN32_WINNT) && \
_WIN32_WINNT >= 0x0601 /* _WIN32_WINNT_WIN7 */
if (threads == 0) {
DWORD winCores = GetActiveProcessorCount(
ALL_PROCESSOR_GROUPS);
threads = (intmax_t)winCores;
}
#endif
if (threads < 0 || threads > INT_MAX) {
return (ARCHIVE_WARN);
}
data->threads = (int)threads;

View file

@ -4427,7 +4427,8 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname)
#else
la_stat(datafork.s, &st) == -1 ||
#endif
(st.st_mode & AE_IFMT) != AE_IFREG)
(((st.st_mode & AE_IFMT) != AE_IFREG) &&
((st.st_mode & AE_IFMT) != AE_IFDIR)))
goto skip_appledouble;
/*

View file

@ -158,7 +158,7 @@ int __archive_write_program_write(struct archive_write_filter *,
struct archive_write_program_data *, const void *, size_t);
/*
* Get a encryption passphrase.
* Get an encryption passphrase.
*/
const char * __archive_write_get_passphrase(struct archive_write *a);
#endif

View file

@ -387,7 +387,7 @@ archive_write_gnutar_header(struct archive_write *a,
if (r != 0) {
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Pathame");
"Can't allocate memory for pathname");
ret = ARCHIVE_FATAL;
goto exit_write_header;
}

View file

@ -30,14 +30,9 @@
#endif
#include "archive_write_private.h"
int
archive_write_set_passphrase(struct archive *_a, const char *p)
static int
set_passphrase(struct archive_write *a, const char *p)
{
struct archive_write *a = (struct archive_write *)_a;
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
"archive_write_set_passphrase");
if (p == NULL || p[0] == '\0') {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Empty passphrase is unacceptable");
@ -54,6 +49,18 @@ archive_write_set_passphrase(struct archive *_a, const char *p)
}
int
archive_write_set_passphrase(struct archive *_a, const char *p)
{
struct archive_write *a = (struct archive_write *)_a;
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
"archive_write_set_passphrase");
return (set_passphrase(a, p));
}
int
archive_write_set_passphrase_callback(struct archive *_a, void *client_data,
archive_passphrase_callback *cb)
@ -80,15 +87,9 @@ __archive_write_get_passphrase(struct archive_write *a)
const char *p;
p = a->passphrase_callback(&a->archive,
a->passphrase_client_data);
if (p != NULL) {
a->passphrase = strdup(p);
if (a->passphrase == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate data for passphrase");
return (NULL);
}
return (a->passphrase);
}
set_passphrase(a, p);
a->passphrase_callback = NULL;
a->passphrase_client_data = NULL;
}
return (NULL);
return (a->passphrase);
}

View file

@ -124,7 +124,7 @@ to read the entire file into memory at once and return the
entire file to libarchive as a single block;
other clients may begin asynchronous I/O operations for the
next block on each request.
.Ss Decompresssion Layer
.Ss Decompression Layer
The decompression layer not only handles decompression,
it also buffers data so that the format handlers see a
much nicer I/O model.

View file

@ -172,6 +172,7 @@ IF(ENABLE_TEST)
test_read_format_ustar_filename.c
test_read_format_warc.c
test_read_format_xar.c
test_read_format_xar_doublelink.c
test_read_format_zip.c
test_read_format_zip_7075_utf8_paths.c
test_read_format_zip_comment_stored.c

View file

@ -195,7 +195,6 @@ compat_lzip_4(const char *name)
assertEqualString("test.bin", archive_entry_pathname(ae));
/* Verify the end-of-archive. */
archive_set_error(a, ARCHIVE_OK, NULL);
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify that the format detection worked. */

View file

@ -0,0 +1,55 @@
/*-
* Copyright (c) 2024 Martin Matuska
* 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 __LIBARCHIVE_BUILD
DEFINE_TEST(test_read_format_xar_doublelink)
{
const char *refname = "test_read_format_xar_doublelink.xar";
struct archive *a;
struct archive_entry *ae;
extract_reference_file(refname);
/* Verify with seeking reader. */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
if(ARCHIVE_OK != archive_read_support_format_xar(a)) {
skipping("XAR format unsupported");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname,
10240));
assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
assertEqualString(archive_error_string(a),
"File with multiple link targets");
assert(archive_errno(a) != 0);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View file

@ -0,0 +1,12 @@
begin 664 test_read_format_xar_doublelink.xar
M>&%R(0`<``$````````!0`````````/7`````7B<[9/!<L(@%$7W?@7#/H60
MU'0R!'?]`KOICDF>D3&``]'1?GT!-1U;;:=[5[G<=WB0=P>^..@![<%Y94V#
M\R>*$9C6=LKT#7Y;OF8O>"%F_""=F"$^VC9\$&\=R#'LR$:E03#*RHR6&2N6
MM*KIO,YS3JZ1M&D-[<;O-/+C<8`&^[7,<:P@;E<K#Z.@G)Q5<KWZB,TY22*V
M()<>:;52`R#5A6N?VQ@9CHIN.#_IY(['+:!!F4V#K5.],G+`8BU=%SU.8OF?
MH#*V`U%5K"@9)Z=5*G2P5RT8*YY+3J9%*ND(T?D\%/3$[U0G<DK#+T9ULCPX
MH75PHDA6/U']A>J=W6T3=E+);&^E4=0%?0^#N\00;G(;8U7`]!<F?\'D%"J)
MX[Y.@WU/@]U)(_\SACO$8_X_YA_&$]\F)^FE?@)<4AJ<B%QTTZN3JTL:$,<5
<`XH;(KD-Q0=XG.V3P7+"(!1%]WX%PSZ%D-1T,@``
`
end

View file

@ -236,3 +236,87 @@ DEFINE_TEST(test_write_disk_appledouble)
assertEqualFile("hfscmp/file3", "nocmp/file3");
#endif
}
/* Test writing apple doubles to disk from zip format */
DEFINE_TEST(test_write_disk_appledouble_zip)
{
#if !defined(__APPLE__) || !defined(UF_COMPRESSED) || !defined(HAVE_SYS_XATTR_H)\
|| !defined(HAVE_ZLIB_H)
skipping("MacOS-specific AppleDouble test");
#else
const char *refname = "test_write_disk_appledouble_zip.zip";
struct archive *ad, *a;
struct archive_entry *ae;
struct stat st;
extract_reference_file(refname);
/*
* Extract an archive to disk.
*/
assert((ad = archive_write_disk_new()) != NULL);
assertEqualIntA(ad, ARCHIVE_OK,
archive_write_disk_set_standard_lookup(ad));
assertEqualIntA(ad, ARCHIVE_OK,
archive_write_disk_set_options(ad,
ARCHIVE_EXTRACT_TIME |
ARCHIVE_EXTRACT_SECURE_SYMLINKS |
ARCHIVE_EXTRACT_SECURE_NODOTDOT));
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a,
refname, 512 * 20));
/* Skip The top level directory */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("apple_double_dir/", archive_entry_pathname(ae));
/* Extract apple_double_test */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("apple_double_dir/apple_double_dir_test/", archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
/* Extract ._apple_double_dir_test which will be merged into apple_double_dir_test as metadata. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("apple_double_dir/._apple_double_dir_test", archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
/* Extract test_file */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("apple_double_dir/test_file", archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
/* Extract ._test_file which will be merged into test_file as metadata. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("apple_double_dir/._test_file", archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad));
/* Test test_file */
assertEqualInt(0, stat("apple_double_dir/test_file", &st));
assertFileSize("apple_double_dir/test_file", 5);
failure("'%s' should have Resource Fork", "test_file");
assertEqualInt(1, has_xattr("apple_double_dir/test_file", "com.apple.ResourceFork"));
/* Test apple_double_dir_test */
failure("'%s' should have quarantine xattr", "apple_double_dir_test");
assertEqualInt(1, has_xattr("apple_double_dir/apple_double_dir_test", "com.apple.quarantine"));
/* Test ._test_file. */
failure("'apple_double_dir/._test_file' should be merged and removed");
assertFileNotExists("apple_double_dir/._test_file");
/* Test ._apple_double_dir_test */
failure("'apple_double_dir/._._apple_double_dir_test' should be merged and removed");
assertFileNotExists("apple_double_dir/._apple_double_dir_test");
assertChdir("..");
#endif
}

View file

@ -0,0 +1,27 @@
begin 644 test_write_disk_appledouble_zip.zip
M4$L#!`H```````MM?%@````````````````1`!``87!P;&5?9&]U8FQE7V1I
M<B]56`P`O=4%9K75!6;U`10`4$L#!`H```````MM?%@````````````````G
M`!``87!P;&5?9&]U8FQE7V1I<B]A<'!L95]D;W5B;&5?9&ER7W1E<W0O55@,
M`+W5!6:UU05F]0$4`%!+`P04``@`"``+;7Q8````````````````*``0`&%P
M<&QE7V1O=6)L95]D:7(O+E]A<'!L95]D;W5B;&5?9&ER7W1E<W156`P`O=4%
M9K75!6;U`10`8V`58V=@8F#P34Q6\`]6B%"``I`8`R<0&P%Q!1"#^*L8B`*.
M(2%!4"9(QPP@%D)3PH@0%TW.S]5++"C(2=4K+$TL2LPKR<Q+92C4-S"P,+8V
M@`)K:P8`4$L'"!2N=6M7````J@```%!+`P04``@`"`!93GQ8````````````
M````&@`0`&%P<&QE7V1O=6)L95]D:7(O=&5S=%]F:6QE55@,`+'5!6;IGP5F
M]0$4`"M)+2[A`@!02P<(QC6Y.P<````%````4$L#!!0`"``(`%E.?%@`````
M```````````<`!``87!P;&5?9&]U8FQE7V1I<B\N7W1E<W1?9FEL9558#`"Q
MU05FZ9\%9O4!%`!C8!5C9V!B8/!-3%;P#U:(4(`"D!@#)Q`;`;$;$(/X%4#,
MQT`0.(:$!$&9%5",`8I2B_-+BY)3%=+RB[*Y`%!+!P@HPLP3/@```(8```!0
M2P$"%0,*```````+;7Q8````````````````$0`,``````````!`[4$`````
M87!P;&5?9&]U8FQE7V1I<B]56`@`O=4%9K75!6902P$"%0,*```````+;7Q8
M````````````````)P`,``````````!`[4$_````87!P;&5?9&]U8FQE7V1I
M<B]A<'!L95]D;W5B;&5?9&ER7W1E<W0O55@(`+W5!6:UU05F4$L!`A4#%``(
M``@`"VU\6!2N=6M7````J@```"@`#```````````0*2!E````&%P<&QE7V1O
M=6)L95]D:7(O+E]A<'!L95]D;W5B;&5?9&ER7W1E<W156`@`O=4%9K75!690
M2P$"%0,4``@`"`!93GQ8QC6Y.P<````%````&@`,``````````!`I(%1`0``
M87!P;&5?9&]U8FQE7V1I<B]T97-T7V9I;&556`@`L=4%9NF?!6902P$"%0,4
M``@`"`!93GQ8*,+,$SX```"&````'``,``````````!`I(&P`0``87!P;&5?
M9&]U8FQE7V1I<B\N7W1E<W1?9FEL9558"`"QU05FZ9\%9E!+!08`````!0`%
+`+@!``!(`@``````
`
end

View file

@ -76,6 +76,7 @@
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <string.h>
#include <windows.h>
static char *
@ -113,8 +114,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
WriteFile(hStdout, "\r\n", 2, NULL, NULL);
buf[rbytes] = '\0';
/* Remove trailing carriage return(s). */
if (rbytes > 2 && buf[rbytes - 2] == '\r' && buf[rbytes - 1] == '\n')
buf[rbytes - 2] = '\0';
buf[strcspn(buf, "\r\n")] = '\0';
return (buf);
}

View file

@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd March 1, 2024
.Dd April 23, 2024
.Dt TAR 1
.Os
.Sh NAME
@ -644,14 +644,13 @@ A decimal integer from 4 to 7 specifying the lz4 compression block size
.It Cm lz4:block-dependence
Use the previous block of the block being compressed for
a compression dictionary to improve compression ratio.
.It Cm zstd:compression-level
A decimal integer specifying the zstd compression level. Supported values depend
.It Cm zstd:compression-level Ns = Ns Ar N
A decimal integer specifying the zstd compression level.
Supported values depend
on the library version, common values are from 1 to 22.
.It Cm zstd:threads
Specify the number of worker threads to use.
Setting threads to a special value 0 makes
.Xr zstd 1
use as many threads as there are CPU cores on the system.
.It Cm zstd:threads Ns = Ns Ar N
Specify the number of worker threads to use, or 0 to use as many
threads as there are CPU cores in the system.
.It Cm zstd:frame-per-file
Start a new compression frame at the beginning of each file in the
archive.

View file

@ -157,6 +157,7 @@ main(int argc, char **argv)
char *tptr, *uptr;
char possible_help_request;
char buff[16];
long l;
/*
* Use a pointer for consistency, but stack-allocated storage
@ -301,16 +302,15 @@ main(int argc, char **argv)
/* libarchive doesn't need this; just ignore it. */
break;
case 'b': /* SUSv2 */
errno = 0;
tptr = NULL;
t = (int)strtol(bsdtar->argument, &tptr, 10);
if (errno || t <= 0 || t > 8192 ||
l = strtol(bsdtar->argument, &tptr, 10);
if (l <= 0 || l > 8192L ||
*(bsdtar->argument) == '\0' || tptr == NULL ||
*tptr != '\0') {
lafe_errc(1, 0, "Invalid or out of range "
"(1..8192) argument to -b");
}
bsdtar->bytes_per_block = 512 * t;
bsdtar->bytes_per_block = 512 * (int)l;
/* Explicit -b forces last block size. */
bsdtar->bytes_in_last_block = bsdtar->bytes_per_block;
break;
@ -369,44 +369,42 @@ main(int argc, char **argv)
bsdtar->filename = bsdtar->argument;
break;
case OPTION_GID: /* cpio */
errno = 0;
tptr = NULL;
t = (int)strtol(bsdtar->argument, &tptr, 10);
if (errno || t < 0 || *(bsdtar->argument) == '\0' ||
l = strtol(bsdtar->argument, &tptr, 10);
if (l < 0 || l >= INT_MAX || *(bsdtar->argument) == '\0' ||
tptr == NULL || *tptr != '\0') {
lafe_errc(1, 0, "Invalid argument to --gid");
}
bsdtar->gid = t;
bsdtar->gid = (int)l;
break;
case OPTION_GNAME: /* cpio */
bsdtar->gname = bsdtar->argument;
break;
case OPTION_GROUP: /* GNU tar */
errno = 0;
tptr = NULL;
uptr = strchr(bsdtar->argument, ':');
if(uptr != NULL) {
if(uptr[1] == 0) {
if (uptr != NULL) {
if (uptr[1] == '\0') {
lafe_errc(1, 0, "Invalid argument to --group (missing id after :)");
}
uptr[0] = 0;
uptr++;
t = (int)strtol(uptr, &tptr, 10);
if (errno || t < 0 || *uptr == '\0' ||
l = strtol(uptr, &tptr, 10);
if (l < 0 || l >= INT_MAX || *uptr == '\0' ||
tptr == NULL || *tptr != '\0') {
lafe_errc(1, 0, "Invalid argument to --group (%s is not a number)", uptr);
} else {
bsdtar->gid = t;
bsdtar->gid = (int)l;
}
bsdtar->gname = bsdtar->argument;
} else {
t = (int)strtol(bsdtar->argument, &tptr, 10);
if (errno || t < 0 || *(bsdtar->argument) == '\0' ||
l = strtol(bsdtar->argument, &tptr, 10);
if (l < 0 || l >= INT_MAX || *(bsdtar->argument) == '\0' ||
tptr == NULL || *tptr != '\0') {
bsdtar->gname = bsdtar->argument;
} else {
bsdtar->gid = t;
bsdtar->gid = (int)l;
bsdtar->gname = "";
}
}
@ -662,31 +660,30 @@ main(int argc, char **argv)
bsdtar->option_options = bsdtar->argument;
break;
case OPTION_OWNER: /* GNU tar */
errno = 0;
tptr = NULL;
uptr = strchr(bsdtar->argument, ':');
if(uptr != NULL) {
if(uptr[1] == 0) {
if (uptr != NULL) {
if (uptr[1] == 0) {
lafe_errc(1, 0, "Invalid argument to --owner (missing id after :)");
}
uptr[0] = 0;
uptr++;
t = (int)strtol(uptr, &tptr, 10);
if (errno || t < 0 || *uptr == '\0' ||
l = strtol(uptr, &tptr, 10);
if (l < 0 || l >= INT_MAX || *uptr == '\0' ||
tptr == NULL || *tptr != '\0') {
lafe_errc(1, 0, "Invalid argument to --owner (%s is not a number)", uptr);
} else {
bsdtar->uid = t;
bsdtar->uid = (int)l;
}
bsdtar->uname = bsdtar->argument;
} else {
t = (int)strtol(bsdtar->argument, &tptr, 10);
if (errno || t < 0 || *(bsdtar->argument) == '\0' ||
l = strtol(bsdtar->argument, &tptr, 10);
if (l < 0 || l >= INT_MAX || *(bsdtar->argument) == '\0' ||
tptr == NULL || *tptr != '\0') {
bsdtar->uname = bsdtar->argument;
} else {
bsdtar->uid = t;
bsdtar->uid = (int)l;
bsdtar->uname = "";
}
}
@ -748,15 +745,14 @@ main(int argc, char **argv)
bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER;
break;
case OPTION_STRIP_COMPONENTS: /* GNU tar 1.15 */
errno = 0;
tptr = NULL;
t = (int)strtol(bsdtar->argument, &tptr, 10);
if (errno || t < 0 || *(bsdtar->argument) == '\0' ||
l = strtol(bsdtar->argument, &tptr, 10);
if (l < 0 || l > 100000L || *(bsdtar->argument) == '\0' ||
tptr == NULL || *tptr != '\0') {
lafe_errc(1, 0, "Invalid argument to "
"--strip-components");
}
bsdtar->strip_components = t;
bsdtar->strip_components = (int)l;
break;
case 'T': /* GNU tar */
bsdtar->names_from_file = bsdtar->argument;
@ -776,14 +772,13 @@ main(int argc, char **argv)
set_mode(bsdtar, opt);
break;
case OPTION_UID: /* cpio */
errno = 0;
tptr = NULL;
t = (int)strtol(bsdtar->argument, &tptr, 10);
if (errno || t < 0 || *(bsdtar->argument) == '\0' ||
l = strtol(bsdtar->argument, &tptr, 10);
if (l < 0 || l >= INT_MAX || *(bsdtar->argument) == '\0' ||
tptr == NULL || *tptr != '\0') {
lafe_errc(1, 0, "Invalid argument to --uid");
}
bsdtar->uid = t;
bsdtar->uid = (int)l;
break;
case OPTION_UNAME: /* cpio */
bsdtar->uname = bsdtar->argument;

View file

@ -218,12 +218,18 @@ bsdtar_getopt(struct bsdtar *bsdtar)
enum { state_start = 0, state_old_tar, state_next_word,
state_short, state_long };
const struct bsdtar_option *popt, *match = NULL, *match2 = NULL;
const char *p, *long_prefix = "--";
const struct bsdtar_option *popt, *match, *match2;
const char *p, *long_prefix;
size_t optlength;
int opt = '?';
int required = 0;
int opt;
int required;
again:
match = NULL;
match2 = NULL;
long_prefix = "--";
opt = '?';
required = 0;
bsdtar->argument = NULL;
/* First time through, initialize everything. */
@ -310,7 +316,7 @@ bsdtar_getopt(struct bsdtar *bsdtar)
if (opt == '\0') {
/* End of this group; recurse to get next option. */
bsdtar->getopt_state = state_next_word;
return bsdtar_getopt(bsdtar);
goto again;
}
/* Does this option take an argument? */

View file

@ -81,12 +81,18 @@ bsdunzip_getopt(struct bsdunzip *bsdunzip)
{
enum { state_start = 0, state_next_word, state_short, state_long };
const struct bsdunzip_option *popt, *match = NULL, *match2 = NULL;
const char *p, *long_prefix = "--";
const struct bsdunzip_option *popt, *match, *match2;
const char *p, *long_prefix;
size_t optlength;
int opt = OPTION_NONE;
int required = 0;
int opt;
int required;
again:
match = NULL;
match2 = NULL;
long_prefix = "--";
opt = OPTION_NONE;
required = 0;
bsdunzip->argument = NULL;
/* First time through, initialize everything. */
@ -140,7 +146,7 @@ bsdunzip_getopt(struct bsdunzip *bsdunzip)
if (opt == '\0') {
/* End of this group; recurse to get next option. */
bsdunzip->getopt_state = state_next_word;
return bsdunzip_getopt(bsdunzip);
goto again;
}
/* Does this option take an argument? */

View file

@ -25,12 +25,25 @@
*/
#include "test.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
/* Test I arg - file name encoding */
DEFINE_TEST(test_I)
{
const char *reffile = "test_I.zip";
int r;
#if HAVE_SETLOCALE
if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
skipping("en_US.UTF-8 locale not available on this system.");
return;
}
#else
skipping("setlocale() not available on this system.");
#endif
extract_reference_file(reffile);
r = systemf("%s -I UTF-8 %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);