mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-13 14:40:22 +00:00
libarchive: merge from vendor branch
Libarchive 3.7.4 + three fixes from master Security fixes: #2135 rar: Fix OOB in rar e8 filter (CVE-2024-26256) #2145 zip: Fix out of boundary access #2148 rar: Fix OOB in rar delta filter #2149 rar: Fix OOB in rar audio filter 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 #2150 xar: Fix another infinite loop and expat error handling #2108 zip: Update AppleDouble support for directories #2071 zstd: Implement core detectiongit PR: 278588 (exp-run) MFC after: 1 day
This commit is contained in:
commit
13d826ff94
@ -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
|
||||
|
@ -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
|
||||
|
@ -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? */
|
||||
|
@ -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? */
|
||||
|
@ -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 *,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 .
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
@ -3599,7 +3612,15 @@ execute_filter_delta(struct rar_filter *filter, struct rar_virtual_machine *vm)
|
||||
{
|
||||
uint8_t lastbyte = 0;
|
||||
for (idx = i; idx < length; idx += numchannels)
|
||||
{
|
||||
/*
|
||||
* The src block should not overlap with the dst block.
|
||||
* If so it would be better to consider this archive is broken.
|
||||
*/
|
||||
if (src >= dst)
|
||||
return 0;
|
||||
lastbyte = dst[idx] = lastbyte - *src++;
|
||||
}
|
||||
}
|
||||
|
||||
filter->filteredblockaddress = length;
|
||||
@ -3615,7 +3636,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++)
|
||||
@ -3701,6 +3722,13 @@ execute_filter_audio(struct rar_filter *filter, struct rar_virtual_machine *vm)
|
||||
memset(&state, 0, sizeof(state));
|
||||
for (j = i; j < length; j += numchannels)
|
||||
{
|
||||
/*
|
||||
* The src block should not overlap with the dst block.
|
||||
* If so it would be better to consider this archive is broken.
|
||||
*/
|
||||
if (src >= dst)
|
||||
return 0;
|
||||
|
||||
int8_t delta = (int8_t)*src++;
|
||||
uint8_t predbyte, byte;
|
||||
int prederror;
|
||||
|
@ -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';
|
||||
|
@ -2055,6 +2055,12 @@ 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 ||
|
||||
xar->file == xar->hdlink_orgs) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"File with multiple link attributes");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (strcmp(attr->value, "original") == 0) {
|
||||
xar->file->hdnext = xar->hdlink_orgs;
|
||||
xar->hdlink_orgs = xar->file;
|
||||
@ -3251,6 +3257,9 @@ expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts)
|
||||
struct xmlattr_list list;
|
||||
int r;
|
||||
|
||||
if (ud->state != ARCHIVE_OK)
|
||||
return;
|
||||
|
||||
r = expat_xmlattr_setup(a, &list, atts);
|
||||
if (r == ARCHIVE_OK)
|
||||
r = xml_start(a, (const char *)name, &list);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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 attributes");
|
||||
assert(archive_errno(a) != 0);
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
@ -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
|
@ -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
|
||||
}
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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? */
|
||||
|
@ -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? */
|
||||
|
@ -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);
|
||||
|
@ -188,6 +188,7 @@ TESTS_SRCS= \
|
||||
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 \
|
||||
@ -611,6 +612,7 @@ ${PACKAGE}FILES+= test_read_format_ustar_filename_cp866.tar.Z.uu
|
||||
${PACKAGE}FILES+= test_read_format_ustar_filename_eucjp.tar.Z.uu
|
||||
${PACKAGE}FILES+= test_read_format_ustar_filename_koi8r.tar.Z.uu
|
||||
${PACKAGE}FILES+= test_read_format_warc.warc.uu
|
||||
${PACKAGE}FILES+= test_read_format_xar_doublelink.xar.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_7075_utf8_paths.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_7z_deflate.zip.uu
|
||||
@ -679,6 +681,7 @@ ${PACKAGE}FILES+= test_splitted_rar_seek_support_aa.uu
|
||||
${PACKAGE}FILES+= test_splitted_rar_seek_support_ab.uu
|
||||
${PACKAGE}FILES+= test_splitted_rar_seek_support_ac.uu
|
||||
${PACKAGE}FILES+= test_write_disk_appledouble.cpio.gz.uu
|
||||
${PACKAGE}FILES+= test_write_disk_appledouble_zip.zip.uu
|
||||
${PACKAGE}FILES+= test_write_disk_hfs_compression.tgz.uu
|
||||
${PACKAGE}FILES+= test_write_disk_mac_metadata.tar.gz.uu
|
||||
${PACKAGE}FILES+= test_write_disk_no_hfs_compression.tgz.uu
|
||||
|
Loading…
Reference in New Issue
Block a user