libarchive: merge from vendor branch
libarchive 3.8.4
Important bugfixes:
#2787 bsdtar: Fix zero-length pattern issue
#2797 lib: Fix regression introduced in libarchive 3.8.2
when walking enterable but unreadable directories
Obtained from: libarchive
Vendor commit: d114ceee6de08a7a60ff1209492ba38bf9436f79
MFC after: 1 week
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
Nov 17, 2026: libarchive 3.8.3 released
|
||||
Dec 01, 2025: libarchive 3.8.4 released
|
||||
|
||||
Oct 15, 2026: libarchive 3.8.2 released
|
||||
Nov 17, 2025: libarchive 3.8.3 released
|
||||
|
||||
Jun 01, 2026: libarchive 3.8.1 released
|
||||
Oct 15, 2025: libarchive 3.8.2 released
|
||||
|
||||
Jun 01, 2025: libarchive 3.8.1 released
|
||||
|
||||
May 20, 2025: libarchive 3.8.0 released
|
||||
|
||||
|
||||
@@ -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 3008003
|
||||
#define ARCHIVE_VERSION_NUMBER 3008004
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
@@ -177,7 +177,7 @@ __LA_DECL int archive_version_number(void);
|
||||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.8.3"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.8.4"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
|
||||
@@ -490,9 +490,9 @@ aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
|
||||
size_t in_len, uint8_t * const out, size_t *out_len)
|
||||
{
|
||||
uint8_t *const ebuf = ctx->encr_buf;
|
||||
unsigned pos = ctx->encr_pos;
|
||||
unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
|
||||
unsigned i;
|
||||
size_t pos = ctx->encr_pos;
|
||||
size_t max = (in_len < *out_len)? in_len: *out_len;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < max; ) {
|
||||
if (pos == AES_BLOCK_SIZE) {
|
||||
|
||||
@@ -56,10 +56,10 @@ int __libarchive_cryptor_build_hack(void);
|
||||
typedef struct {
|
||||
CCCryptorRef ctx;
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
size_t key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
size_t encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3008003
|
||||
#define ARCHIVE_VERSION_NUMBER 3008004
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
||||
@@ -254,7 +254,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
if (S_ISLNK(st->st_mode)) {
|
||||
size_t linkbuffer_len = st->st_size;
|
||||
char *linkbuffer;
|
||||
int lnklen;
|
||||
ssize_t lnklen;
|
||||
|
||||
linkbuffer = malloc(linkbuffer_len + 1);
|
||||
if (linkbuffer == NULL) {
|
||||
@@ -892,7 +892,7 @@ setup_sparse_fiemap(struct archive_read_disk *a,
|
||||
for (iters = 0; ; ++iters) {
|
||||
int i, r;
|
||||
|
||||
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
|
||||
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
|
||||
if (r < 0) {
|
||||
/* When something error happens, it is better we
|
||||
* should return ARCHIVE_OK because an earlier
|
||||
@@ -1079,4 +1079,3 @@ setup_sparse(struct archive_read_disk *a,
|
||||
#endif
|
||||
|
||||
#endif /* !defined(_WIN32) || defined(__CYGWIN__) */
|
||||
|
||||
|
||||
@@ -2018,11 +2018,8 @@ tree_dup(int fd)
|
||||
}
|
||||
#endif /* F_DUPFD_CLOEXEC */
|
||||
new_fd = dup(fd);
|
||||
if (new_fd != -1) {
|
||||
__archive_ensure_cloexec_flag(new_fd);
|
||||
return (new_fd);
|
||||
}
|
||||
return (-1);
|
||||
__archive_ensure_cloexec_flag(new_fd);
|
||||
return (new_fd);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2144,16 +2141,11 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
|
||||
* so try again for execute. The consequences of not opening this are
|
||||
* unhelpful and unnecessary errors later.
|
||||
*/
|
||||
if (t->initial_dir_fd < 0) {
|
||||
if (t->initial_dir_fd < 0)
|
||||
t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
|
||||
if (t->initial_dir_fd < 0)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
__archive_ensure_cloexec_flag(t->initial_dir_fd);
|
||||
t->working_dir_fd = tree_dup(t->initial_dir_fd);
|
||||
if (t->working_dir_fd < 0)
|
||||
return NULL;
|
||||
return (t);
|
||||
}
|
||||
|
||||
@@ -2359,15 +2351,20 @@ static int
|
||||
tree_dir_next_posix(struct tree *t)
|
||||
{
|
||||
int r;
|
||||
#if defined(HAVE_FDOPENDIR)
|
||||
int fd;
|
||||
#endif
|
||||
const char *name;
|
||||
size_t namelen;
|
||||
|
||||
if (t->d == NULL) {
|
||||
|
||||
#if defined(HAVE_FDOPENDIR)
|
||||
int fd = tree_dup(t->working_dir_fd);
|
||||
if (fd != -1)
|
||||
t->d = fdopendir(fd);
|
||||
if (t->working_dir_fd >= 0) {
|
||||
fd = tree_dup(t->working_dir_fd);
|
||||
if (fd != -1)
|
||||
t->d = fdopendir(fd);
|
||||
}
|
||||
#else /* HAVE_FDOPENDIR */
|
||||
if (tree_enter_working_dir(t) == 0) {
|
||||
t->d = opendir(".");
|
||||
|
||||
@@ -1254,7 +1254,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||
archive_entry_filetype(entry) == AE_IFDIR) {
|
||||
mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(mtree->fd);
|
||||
if (mtree->fd < 0 && (
|
||||
if (mtree->fd == -1 && (
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/*
|
||||
* On Windows, attempting to open a file with an
|
||||
|
||||
@@ -333,7 +333,7 @@ archive_libbsdxml_version(void)
|
||||
const char *
|
||||
archive_libxml2_version(void)
|
||||
{
|
||||
#if HAVE_LIBXML_XMLREADER_H && HAVE_LIBXML2
|
||||
#if HAVE_LIBXML_XMLVERSION_H && HAVE_LIBXML2
|
||||
return LIBXML_DOTTED_VERSION;
|
||||
#else
|
||||
return NULL;
|
||||
|
||||
@@ -821,7 +821,7 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)_a;
|
||||
const size_t max_write = INT_MAX;
|
||||
int ret;
|
||||
ssize_t ret;
|
||||
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||
ARCHIVE_STATE_DATA, "archive_write_data");
|
||||
|
||||
@@ -2561,9 +2561,9 @@ _archive_write_disk_close(struct archive *_a)
|
||||
* for directories. For other file types
|
||||
* we need to verify via fstat() or lstat()
|
||||
*/
|
||||
if (fd < 0 || p->filetype != AE_IFDIR) {
|
||||
if (fd == -1 || p->filetype != AE_IFDIR) {
|
||||
#if HAVE_FSTAT
|
||||
if (fd >= 0 && (
|
||||
if (fd > 0 && (
|
||||
fstat(fd, &st) != 0 ||
|
||||
la_verify_filetype(st.st_mode,
|
||||
p->filetype) == 0)) {
|
||||
@@ -4447,7 +4447,7 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname)
|
||||
*/
|
||||
fd = open(pathname, O_RDONLY | O_BINARY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
if (fd < 0) {
|
||||
if (fd == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to open a restoring file");
|
||||
ret = ARCHIVE_WARN;
|
||||
|
||||
@@ -1000,13 +1000,13 @@ xmlwrite_heap(struct archive_write *a, struct xml_writer *writer,
|
||||
const char *encname;
|
||||
int r;
|
||||
|
||||
r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length);
|
||||
r = xmlwrite_fstring(a, writer, "length", "%ju", (uintmax_t)heap->length);
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset);
|
||||
r = xmlwrite_fstring(a, writer, "offset", "%ju", (uintmax_t)heap->temp_offset);
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size);
|
||||
r = xmlwrite_fstring(a, writer, "size", "%ju", (uintmax_t)heap->size);
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
switch (heap->compression) {
|
||||
@@ -1356,7 +1356,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer,
|
||||
* Make a inode entry, "<inode>".
|
||||
*/
|
||||
r = xmlwrite_fstring(a, writer, "inode",
|
||||
"%jd", archive_entry_ino64(file->entry));
|
||||
"%jd", (intmax_t)archive_entry_ino64(file->entry));
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (archive_entry_dev(file->entry) != 0) {
|
||||
@@ -1378,7 +1378,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer,
|
||||
* Make a user entry, "<uid>" and "<user>.
|
||||
*/
|
||||
r = xmlwrite_fstring(a, writer, "uid",
|
||||
"%d", archive_entry_uid(file->entry));
|
||||
"%jd", (intmax_t)archive_entry_uid(file->entry));
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv);
|
||||
@@ -1404,7 +1404,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer,
|
||||
* Make a group entry, "<gid>" and "<group>.
|
||||
*/
|
||||
r = xmlwrite_fstring(a, writer, "gid",
|
||||
"%d", archive_entry_gid(file->entry));
|
||||
"%jd", (intmax_t)archive_entry_gid(file->entry));
|
||||
if (r < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv);
|
||||
|
||||
@@ -202,7 +202,7 @@ static int64_t
|
||||
file_skip(struct archive *a, void *data, int64_t request)
|
||||
{
|
||||
struct mydata *mydata = (struct mydata *)data;
|
||||
int64_t result = lseek(mydata->fd, SEEK_CUR, request);
|
||||
int64_t result = lseek(mydata->fd, request, SEEK_CUR);
|
||||
if (result >= 0)
|
||||
return result;
|
||||
archive_set_error(a, errno, "Error seeking in '%s'", mydata->filename);
|
||||
|
||||
@@ -94,21 +94,21 @@ searchgid(void)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static int
|
||||
static long
|
||||
altgid(void)
|
||||
{
|
||||
searchgid();
|
||||
return (_alt_gid);
|
||||
}
|
||||
|
||||
static int
|
||||
static long
|
||||
invalidgid(void)
|
||||
{
|
||||
searchgid();
|
||||
return (_invalid_gid);
|
||||
}
|
||||
|
||||
static int
|
||||
static long
|
||||
defaultgid(void)
|
||||
{
|
||||
searchgid();
|
||||
|
||||
@@ -40,7 +40,8 @@ DEFINE_TEST(test_write_filter_bzip2)
|
||||
size_t buffsize, datasize;
|
||||
char path[16];
|
||||
size_t used1, used2;
|
||||
int i, r, use_prog;
|
||||
ssize_t r;
|
||||
int i, use_prog;
|
||||
|
||||
buffsize = 2000000;
|
||||
assert(NULL != (buff = malloc(buffsize)));
|
||||
|
||||
@@ -235,7 +235,9 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result,
|
||||
(*result)[0] = 0;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
char isEnd = 0;
|
||||
do {
|
||||
isEnd = *name == '\0';
|
||||
if (regexec(&rule->re, name, 10, matches, 0))
|
||||
break;
|
||||
|
||||
@@ -290,12 +292,15 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result,
|
||||
}
|
||||
|
||||
realloc_strcat(result, rule->result + j);
|
||||
|
||||
name += matches[0].rm_eo;
|
||||
|
||||
if (!rule->global)
|
||||
break;
|
||||
}
|
||||
if (matches[0].rm_eo > 0) {
|
||||
name += matches[0].rm_eo;
|
||||
} else {
|
||||
// We skip a character because the match is 0-length
|
||||
// so we need to add it to the output
|
||||
realloc_strncat(result, name, 1);
|
||||
name += 1;
|
||||
}
|
||||
} while (rule->global && !isEnd); // Testing one step after because sed et al. run 0-length patterns a last time on the empty string at the end
|
||||
}
|
||||
|
||||
if (got_match)
|
||||
|
||||
@@ -42,7 +42,13 @@ DEFINE_TEST(test_option_s)
|
||||
systemf("%s -cf test1_2.tar -s /d1/d2/ in/d1/foo", testprog);
|
||||
systemf("%s -xf test1_2.tar -C test1", testprog);
|
||||
assertFileContents("foo", 3, "test1/in/d2/foo");
|
||||
|
||||
systemf("%s -cf test1_3.tar -s /o/#/g in/d1/foo", testprog);
|
||||
systemf("%s -xf test1_3.tar -C test1", testprog);
|
||||
assertFileContents("foo", 3, "test1/in/d1/f##");
|
||||
// For the 0-length pattern check, remember that "test1/" isn't part of the string affected by the regexp
|
||||
systemf("%s -cf test1_4.tar -s /f*/\\<~\\>/g in/d1/foo", testprog);
|
||||
systemf("%s -xf test1_4.tar -C test1", testprog);
|
||||
assertFileContents("foo", 3, "test1/<>i<>n<>/<>d<>1<>/<f><>o<>o<>");
|
||||
/*
|
||||
* Test 2: Basic substitution when extracting archive.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user