Update vendor/libarchive to git d85976e7ff4a062e1de6e04dab7bb78e3344768f

Fixed vendor issues:
Issue 553: Fix broken decryption for ZIP files
Issue 657: Allow up to 8k for the test root directory name
Issue 682: Correctly write gnutar filenames of exactly 512 bytes
Issue 708: tar should fail if a named input file is missing
PR 715: Fix libarchive/archive_read_support_format_mtree.c:1388:11:
        error: array subscript is above array bounds
This commit is contained in:
Martin Matuska
2016-06-18 08:25:31 +00:00
parent 8eb6639196
commit dc919cebaf
23 changed files with 493 additions and 144 deletions
+3
View File
@@ -533,6 +533,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_write_format_cpio_newc.c \
libarchive/test/test_write_format_cpio_odc.c \
libarchive/test/test_write_format_gnutar.c \
libarchive/test/test_write_format_gnutar_filenames.c \
libarchive/test/test_write_format_iso9660.c \
libarchive/test/test_write_format_iso9660_boot.c \
libarchive/test/test_write_format_iso9660_empty.c \
@@ -909,6 +910,7 @@ bsdtar_test_SOURCES= \
tar/test/test_format_newc.c \
tar/test/test_help.c \
tar/test/test_leading_slash.c \
tar/test/test_missing_file.c \
tar/test/test_option_C_upper.c \
tar/test/test_option_H_upper.c \
tar/test/test_option_L_upper.c \
@@ -1064,6 +1066,7 @@ bsdcpio_test_SOURCES= \
cpio/test/test_extract_cpio_xz.c \
cpio/test/test_format_newc.c \
cpio/test/test_gcpio_compat.c \
cpio/test/test_missing_file.c \
cpio/test/test_option_0.c \
cpio/test/test_option_B_upper.c \
cpio/test/test_option_C_upper.c \
+49 -26
View File
@@ -2534,18 +2534,36 @@ usage(const char *program)
static char *
get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
size_t tried_size, buff_size;
char *buff, *tried, *pwd = NULL, *p = NULL;
#ifdef PATH_MAX
buff_size = PATH_MAX;
#else
buff_size = 8192;
#endif
buff = calloc(buff_size, 1);
if (buff == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* Allocate a buffer to hold the various directories we checked. */
tried_size = buff_size * 2;
tried = calloc(tried_size, 1);
if (tried == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* If a dir was specified, try that */
if (d != NULL) {
pwd = NULL;
snprintf(buff, sizeof(buff), "%s", d);
snprintf(buff, buff_size, "%s", d);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
goto failure;
}
@@ -2559,48 +2577,48 @@ get_refdir(const char *d)
pwd[strlen(pwd) - 1] = '\0';
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
snprintf(buff, buff_size, "%s", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd);
snprintf(buff, buff_size, "%s/test", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(PROGRAM_ALIAS)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#endif
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
snprintf(buff, buff_size, "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
snprintf(buff, buff_size, "%s/test", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
}
failure:
@@ -2615,7 +2633,12 @@ get_refdir(const char *d)
success:
free(p);
free(pwd);
return strdup(buff);
free(tried);
/* Copy result into a fresh buffer to reduce memory usage. */
p = strdup(buff);
free(buff);
return p;
}
int
+5 -4
View File
@@ -252,7 +252,7 @@ esac
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h copyfile.h ctype.h])
AC_CHECK_HEADERS([copyfile.h ctype.h])
AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h grp.h])
AC_CACHE_CHECK([whether EXT2_IOC_GETFLAGS is usable],
@@ -272,7 +272,7 @@ AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h linux/types.h])
AC_CHECK_HEADERS([locale.h paths.h poll.h pthread.h pwd.h])
AC_CHECK_HEADERS([readpassphrase.h signal.h spawn.h])
AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h])
AC_CHECK_HEADERS([sys/cdefs.h sys/extattr.h])
AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h])
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/statfs.h sys/statvfs.h])
AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h])
@@ -644,7 +644,7 @@ AC_CHECK_MEMBER(struct dirent.d_namlen,,,
# Check for Extended Attributes support
AC_ARG_ENABLE([xattr],
AS_HELP_STRING([--disable-xattr],
[Enable Extended Attributes support (default: check)]))
[Disable Extended Attributes support (default: check)]))
if test "x$enable_xattr" != "xno"; then
AC_CHECK_HEADERS([attr/xattr.h])
@@ -670,9 +670,10 @@ fi
#
AC_ARG_ENABLE([acl],
AS_HELP_STRING([--disable-acl],
[Enable ACL support (default: check)]))
[Disable ACL support (default: check)]))
if test "x$enable_acl" != "xno"; then
AC_CHECK_HEADERS([acl/libacl.h])
AC_CHECK_HEADERS([sys/acl.h])
AC_CHECK_LIB([acl],[acl_get_file])
AC_CHECK_FUNCS([acl_create_entry acl_init acl_set_fd acl_set_fd_np acl_set_file])
+1
View File
@@ -25,6 +25,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
test_extract_cpio_xz
test_format_newc.c
test_gcpio_compat.c
test_missing_file.c
test_option_0.c
test_option_B_upper.c
test_option_C_upper.c
+49 -26
View File
@@ -2535,18 +2535,36 @@ usage(const char *program)
static char *
get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
size_t tried_size, buff_size;
char *buff, *tried, *pwd = NULL, *p = NULL;
#ifdef PATH_MAX
buff_size = PATH_MAX;
#else
buff_size = 8192;
#endif
buff = calloc(buff_size, 1);
if (buff == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* Allocate a buffer to hold the various directories we checked. */
tried_size = buff_size * 2;
tried = calloc(tried_size, 1);
if (tried == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* If a dir was specified, try that */
if (d != NULL) {
pwd = NULL;
snprintf(buff, sizeof(buff), "%s", d);
snprintf(buff, buff_size, "%s", d);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
goto failure;
}
@@ -2560,48 +2578,48 @@ get_refdir(const char *d)
pwd[strlen(pwd) - 1] = '\0';
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
snprintf(buff, buff_size, "%s", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd);
snprintf(buff, buff_size, "%s/test", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(PROGRAM_ALIAS)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#endif
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
snprintf(buff, buff_size, "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
snprintf(buff, buff_size, "%s/test", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
}
failure:
@@ -2616,7 +2634,12 @@ get_refdir(const char *d)
success:
free(p);
free(pwd);
return strdup(buff);
free(tried);
/* Copy result into a fresh buffer to reduce memory usage. */
p = strdup(buff);
free(buff);
return p;
}
int
+52
View File
@@ -0,0 +1,52 @@
/*-
* Copyright (c) 2016 Tim Kientzle
* 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"
__FBSDID("$FreeBSD$");
DEFINE_TEST(test_missing_file)
{
int r;
assertMakeFile("file1", 0644, "file1");
assertMakeFile("file2", 0644, "file2");
assertMakeFile("filelist1", 0644, "file1\nfile2\n");
r = systemf("%s -o <filelist1 >stdout1 2>stderr1", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "stderr1");
assertMakeFile("filelist2", 0644, "file1\nfile2\nfile3\n");
r = systemf("%s -o <filelist2 >stdout2 2>stderr2", testprog);
assert(r != 0);
assertMakeFile("filelist3", 0644, "");
r = systemf("%s -o <filelist3 >stdout3 2>stderr3", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "stderr3");
assertMakeFile("filelist4", 0644, "file3\n");
r = systemf("%s -o <filelist4 >stdout4 2>stderr4", testprog);
assert(r != 0);
}
+2 -7
View File
@@ -91,16 +91,11 @@ archive_entry_xattr_add_entry(struct archive_entry *entry,
{
struct ae_xattr *xp;
for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
;
if ((xp = (struct ae_xattr *)malloc(sizeof(struct ae_xattr))) == NULL)
/* XXX Error XXX */
return;
__archive_errx(1, "Out of memory");
if ((xp->name = strdup(name)) == NULL)
/* XXX Error XXX */
return;
__archive_errx(1, "Out of memory");
if ((xp->value = malloc(size)) != NULL) {
memcpy(xp->value, value, size);
@@ -1385,12 +1385,12 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
"Missing number");
return ARCHIVE_WARN;
}
numbers[argc++] = (unsigned long)mtree_atol(&p);
if (argc > MAX_PACK_ARGS) {
if (argc >= MAX_PACK_ARGS) {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
"Too many arguments");
return ARCHIVE_WARN;
}
numbers[argc++] = (unsigned long)mtree_atol(&p);
}
if (argc < 2) {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+11 -2
View File
@@ -181,6 +181,14 @@ struct zip {
char init_decryption;
/* Decryption buffer. */
/*
* The decrypted data starts at decrypted_ptr and
* extends for decrypted_bytes_remaining. Decryption
* adds new data to the end of this block, data is returned
* to clients from the beginning. When the block hits the
* end of decrypted_buffer, it has to be shuffled back to
* the beginning of the buffer.
*/
unsigned char *decrypted_buffer;
unsigned char *decrypted_ptr;
size_t decrypted_buffer_size;
@@ -1293,8 +1301,9 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
if (zip->tctx_valid || zip->cctx_valid) {
if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) {
size_t buff_remaining = zip->decrypted_buffer_size
- (zip->decrypted_ptr - zip->decrypted_buffer);
size_t buff_remaining =
(zip->decrypted_buffer + zip->decrypted_buffer_size)
- (zip->decrypted_ptr + zip->decrypted_bytes_remaining);
if (buff_remaining > (size_t)bytes_avail)
buff_remaining = (size_t)bytes_avail;
+11 -3
View File
@@ -468,9 +468,17 @@ permissive_name_w(struct archive_write_disk *a)
return (-1);
archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1);
a->name = a->_name_data.s;
/* Prepend "\\?\" and drive name. */
archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
archive_wstrncat(&(a->_name_data), wsp, l);
/* Prepend "\\?\" and drive name if not already added. */
if (l > 3 && wsp[0] == L'\\' && wsp[1] == L'\\' &&
wsp[2] == L'?' && wsp[3] == L'\\')
{
archive_wstrncpy(&(a->_name_data), wsp, l);
}
else
{
archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
archive_wstrncat(&(a->_name_data), wsp, l);
}
archive_wstrncat(&(a->_name_data), L"\\", 1);
archive_wstrcat(&(a->_name_data), wn);
a->name = a->_name_data.s;
+1
View File
@@ -43,6 +43,7 @@
.Nm archive_write_add_filter_program ,
.Nm archive_write_add_filter_uuencode ,
.Nm archive_write_add_filter_xz
.Nd functions enabling output filters
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS
+12 -10
View File
@@ -467,7 +467,7 @@ archive_write_gnutar_header(struct archive_write *a,
}
}
if (gnutar->linkname_length > GNUTAR_linkname_size) {
size_t todo = gnutar->linkname_length;
size_t length = gnutar->linkname_length + 1;
struct archive_entry *temp = archive_entry_new2(&a->archive);
/* Uname/gname here don't really matter since no one reads them;
@@ -476,7 +476,7 @@ archive_write_gnutar_header(struct archive_write *a,
archive_entry_set_gname(temp, "wheel");
archive_entry_set_pathname(temp, "././@LongLink");
archive_entry_set_size(temp, gnutar->linkname_length + 1);
archive_entry_set_size(temp, length);
ret = archive_format_gnutar_header(a, buff, temp, 'K');
if (ret < ARCHIVE_WARN)
goto exit_write_header;
@@ -484,11 +484,12 @@ archive_write_gnutar_header(struct archive_write *a,
if(ret < ARCHIVE_WARN)
goto exit_write_header;
archive_entry_free(temp);
/* Write as many 512 bytes blocks as needed to write full name. */
ret = __archive_write_output(a, gnutar->linkname, todo);
/* Write name and trailing null byte. */
ret = __archive_write_output(a, gnutar->linkname, length);
if(ret < ARCHIVE_WARN)
goto exit_write_header;
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
/* Pad to 512 bytes */
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
if (ret < ARCHIVE_WARN)
goto exit_write_header;
}
@@ -496,7 +497,7 @@ archive_write_gnutar_header(struct archive_write *a,
/* If pathname is longer than 100 chars we need to add an 'L' header. */
if (gnutar->pathname_length > GNUTAR_name_size) {
const char *pathname = gnutar->pathname;
size_t todo = gnutar->pathname_length;
size_t length = gnutar->pathname_length + 1;
struct archive_entry *temp = archive_entry_new2(&a->archive);
/* Uname/gname here don't really matter since no one reads them;
@@ -505,7 +506,7 @@ archive_write_gnutar_header(struct archive_write *a,
archive_entry_set_gname(temp, "wheel");
archive_entry_set_pathname(temp, "././@LongLink");
archive_entry_set_size(temp, gnutar->pathname_length + 1);
archive_entry_set_size(temp, length);
ret = archive_format_gnutar_header(a, buff, temp, 'L');
if (ret < ARCHIVE_WARN)
goto exit_write_header;
@@ -513,11 +514,12 @@ archive_write_gnutar_header(struct archive_write *a,
if(ret < ARCHIVE_WARN)
goto exit_write_header;
archive_entry_free(temp);
/* Write as many 512 bytes blocks as needed to write full name. */
ret = __archive_write_output(a, pathname, todo);
/* Write pathname + trailing null byte. */
ret = __archive_write_output(a, pathname, length);
if(ret < ARCHIVE_WARN)
goto exit_write_header;
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
/* Pad to multiple of 512 bytes. */
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
if (ret < ARCHIVE_WARN)
goto exit_write_header;
}
+10 -8
View File
@@ -6225,7 +6225,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
unsigned char *p;
size_t l;
int r;
int ffmax, parent_len;
size_t ffmax, parent_len;
static const struct archive_rb_tree_ops rb_ops = {
isoent_cmp_node_joliet, isoent_cmp_key_joliet
};
@@ -6239,7 +6239,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
else
ffmax = 128;
r = idr_start(a, idr, isoent->children.cnt, ffmax, 6, 2, &rb_ops);
r = idr_start(a, idr, isoent->children.cnt, (int)ffmax, 6, 2, &rb_ops);
if (r < 0)
return (r);
@@ -6252,7 +6252,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
int ext_off, noff, weight;
size_t lt;
if ((int)(l = np->file->basename_utf16.length) > ffmax)
if ((l = np->file->basename_utf16.length) > ffmax)
l = ffmax;
p = malloc((l+1)*2);
@@ -6285,7 +6285,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
/*
* Get a length of MBS of a full-pathname.
*/
if ((int)np->file->basename_utf16.length > ffmax) {
if (np->file->basename_utf16.length > ffmax) {
if (archive_strncpy_l(&iso9660->mbs,
(const char *)np->identifier, l,
iso9660->sconv_from_utf16be) != 0 &&
@@ -6302,7 +6302,9 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
/* If a length of full-pathname is longer than 240 bytes,
* it violates Joliet extensions regulation. */
if (parent_len + np->mb_len > 240) {
if (parent_len > 240
|| np->mb_len > 240
|| parent_len + np->mb_len > 240) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"The regulation of Joliet extensions;"
" A length of a full-pathname of `%s' is "
@@ -6314,11 +6316,11 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
/* Make an offset of the number which is used to be set
* hexadecimal number to avoid duplicate identifier. */
if ((int)l == ffmax)
if (l == ffmax)
noff = ext_off - 6;
else if ((int)l == ffmax-2)
else if (l == ffmax-2)
noff = ext_off - 4;
else if ((int)l == ffmax-4)
else if (l == ffmax-4)
noff = ext_off - 2;
else
noff = ext_off;
+1 -1
View File
@@ -32,7 +32,7 @@
.Nm archive_write_set_format_option ,
.Nm archive_write_set_option ,
.Nm archive_write_set_options
.Nd functions controlling options for reading archives
.Nd functions controlling options for writing archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS
-1
View File
@@ -65,7 +65,6 @@ Later variants have extended this by either appropriating undefined
areas of the header record, extending the header to multiple records,
or by storing special entries that modify the interpretation of
subsequent entries.
.Pp
.Bl -tag -width indent
.It Cm gnutar
The
+1 -1
View File
@@ -28,7 +28,7 @@
.Dt LIBARCHIVE_CHANGES 3
.Os
.Sh NAME
.Nm changes in libarchive interface
.Nd changes in libarchive interface
.\"
.Sh CHANGES IN LIBARCHIVE 3
This page describes user-visible changes in libarchive3, and lists
+1
View File
@@ -222,6 +222,7 @@ IF(ENABLE_TEST)
test_write_format_cpio_newc.c
test_write_format_cpio_odc.c
test_write_format_gnutar.c
test_write_format_gnutar_filenames.c
test_write_format_iso9660.c
test_write_format_iso9660_boot.c
test_write_format_iso9660_empty.c
+49 -26
View File
@@ -2533,18 +2533,36 @@ usage(const char *program)
static char *
get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
size_t tried_size, buff_size;
char *buff, *tried, *pwd = NULL, *p = NULL;
#ifdef PATH_MAX
buff_size = PATH_MAX;
#else
buff_size = 8192;
#endif
buff = calloc(buff_size, 1);
if (buff == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* Allocate a buffer to hold the various directories we checked. */
tried_size = buff_size * 2;
tried = calloc(tried_size, 1);
if (tried == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* If a dir was specified, try that */
if (d != NULL) {
pwd = NULL;
snprintf(buff, sizeof(buff), "%s", d);
snprintf(buff, buff_size, "%s", d);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
goto failure;
}
@@ -2558,48 +2576,48 @@ get_refdir(const char *d)
pwd[strlen(pwd) - 1] = '\0';
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
snprintf(buff, buff_size, "%s", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd);
snprintf(buff, buff_size, "%s/test", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(PROGRAM_ALIAS)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#endif
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
snprintf(buff, buff_size, "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
snprintf(buff, buff_size, "%s/test", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
}
failure:
@@ -2614,7 +2632,12 @@ get_refdir(const char *d)
success:
free(p);
free(pwd);
return strdup(buff);
free(tried);
/* Copy result into a fresh buffer to reduce memory usage. */
p = strdup(buff);
free(buff);
return p;
}
int
@@ -0,0 +1,145 @@
/*-
* Copyright (c) 2016 Tim Kientzle
* 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"
__FBSDID("$FreeBSD$");
/*
* Inspired by Github issue #682, which reported that gnutar filenames
* of exactly 512 bytes weren't getting written correctly.
*
* This writes a filename of every length from 1 to 2000 bytes and
* reads back to verify it.
*/
static char filename[1024];
DEFINE_TEST(test_write_format_gnutar_filenames)
{
size_t buffsize = 1000000;
char *buff;
struct archive_entry *ae, *template;
struct archive *a;
size_t used;
buff = malloc(buffsize); /* million bytes of work area */
assert(buff != NULL);
/* Create a template entry. */
assert((template = archive_entry_new()) != NULL);
archive_entry_set_atime(template, 2, 20);
archive_entry_set_birthtime(template, 3, 30);
archive_entry_set_ctime(template, 4, 40);
archive_entry_set_mtime(template, 5, 50);
archive_entry_set_mode(template, S_IFREG | 0755);
archive_entry_set_size(template, 8);
for (int i = 0; i < 2000; ++i) {
filename[i] = 'a';
filename[i + 1] = '\0';
archive_entry_copy_pathname(template, filename);
/* Write a one-item gnutar format archive. */
assert((a = archive_write_new()) != NULL);
assertA(0 == archive_write_set_format_gnutar(a));
assertA(0 == archive_write_add_filter_none(a));
assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, template));
assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
/* Read back and verify the filename. */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, 0, archive_read_support_format_all(a));
assertEqualIntA(a, 0, archive_read_support_filter_all(a));
assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertEqualString(filename, archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
archive_entry_free(template);
free(buff);
}
DEFINE_TEST(test_write_format_gnutar_linknames)
{
size_t buffsize = 1000000;
char *buff;
struct archive_entry *ae, *template;
struct archive *a;
size_t used;
buff = malloc(buffsize); /* million bytes of work area */
assert(buff != NULL);
/* Create a template entry. */
assert((template = archive_entry_new()) != NULL);
archive_entry_set_atime(template, 2, 20);
archive_entry_set_birthtime(template, 3, 30);
archive_entry_set_ctime(template, 4, 40);
archive_entry_set_mtime(template, 5, 50);
archive_entry_set_mode(template, S_IFLNK | 0755);
archive_entry_copy_pathname(template, "link");
for (int i = 0; i < 2000; ++i) {
filename[i] = 'a';
filename[i + 1] = '\0';
archive_entry_copy_symlink(template, filename);
/* Write a one-item gnutar format archive. */
assert((a = archive_write_new()) != NULL);
assertA(0 == archive_write_set_format_gnutar(a));
assertA(0 == archive_write_add_filter_none(a));
assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, template));
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
/* Read back and verify the filename. */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, 0, archive_read_support_format_all(a));
assertEqualIntA(a, 0, archive_read_support_filter_all(a));
assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertEqualString("link", archive_entry_pathname(ae));
assertEqualString(filename, archive_entry_symlink(ae));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
archive_entry_free(template);
free(buff);
}
+1
View File
@@ -25,6 +25,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
test_format_newc.c
test_help.c
test_leading_slash.c
test_missing_file.c
test_option_C_upper.c
test_option_H_upper.c
test_option_L_upper.c
+49 -26
View File
@@ -2535,18 +2535,36 @@ usage(const char *program)
static char *
get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
size_t tried_size, buff_size;
char *buff, *tried, *pwd = NULL, *p = NULL;
#ifdef PATH_MAX
buff_size = PATH_MAX;
#else
buff_size = 8192;
#endif
buff = calloc(buff_size, 1);
if (buff == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* Allocate a buffer to hold the various directories we checked. */
tried_size = buff_size * 2;
tried = calloc(tried_size, 1);
if (tried == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* If a dir was specified, try that */
if (d != NULL) {
pwd = NULL;
snprintf(buff, sizeof(buff), "%s", d);
snprintf(buff, buff_size, "%s", d);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
goto failure;
}
@@ -2560,48 +2578,48 @@ get_refdir(const char *d)
pwd[strlen(pwd) - 1] = '\0';
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
snprintf(buff, buff_size, "%s", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd);
snprintf(buff, buff_size, "%s/test", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(PROGRAM_ALIAS)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#endif
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
snprintf(buff, buff_size, "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
snprintf(buff, buff_size, "%s/test", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
}
failure:
@@ -2616,7 +2634,12 @@ get_refdir(const char *d)
success:
free(p);
free(pwd);
return strdup(buff);
free(tried);
/* Copy result into a fresh buffer to reduce memory usage. */
p = strdup(buff);
free(buff);
return p;
}
int
+37
View File
@@ -0,0 +1,37 @@
/*-
* Copyright (c) 2016 Tim Kientzle
* 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"
__FBSDID("$FreeBSD$");
DEFINE_TEST(test_missing_file)
{
assertMakeFile("file1", 0644, "file1");
assertMakeFile("file2", 0644, "file2");
assert(0 == systemf("%s -cf archive.tar file1 file2 2>stderr1", testprog));
assertEmptyFile("stderr1");
assert(0 != systemf("%s -cf archive.tar file1 file2 file3 2>stderr2", testprog));
assert(0 != systemf("%s -cf archive.tar 2>stderr3", testprog));
assert(0 != systemf("%s -cf archive.tar file3 2>stderr4", testprog));
}
+1 -1
View File
@@ -884,7 +884,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
else if (r != ARCHIVE_OK) {
lafe_warnc(archive_errno(disk),
"%s", archive_error_string(disk));
if (r == ARCHIVE_FATAL) {
if (r == ARCHIVE_FATAL || r == ARCHIVE_FAILED) {
bsdtar->return_value = 1;
return;
} else if (r < ARCHIVE_WARN)