MFV r347989:
Sync libarchive with vendor. Relevant vendor changes: Issue #795: XAR - do not try to add xattrs without an allocated name PR #812: non-recursive option for extract and list PR #958: support reading metadata from compressed files PR #999: add --exclude-vcs option to bsdtar Issue #1062: treat empty archives with a GNU volume header as valid PR #1074: Handle ZIP files with trailing 0s in the extra fields (Android APK archives) PR #1109: Ignore padding in Zip extra field data (Android APK archives) PR #1167: fix problems related to unreadable directories Issue #1168: fix handling of strtol() and strtoul() PR #1172: RAR5 - fix invalid window buffer read in E8E9 filter PR #1174: ZIP reader - fix of MSZIP signature parsing PR #1175: gzip filter - fix reading files larger than 4GB from memory PR #1177: gzip filter - fix memory leak with repeated header reads PR #1180: ZIP reader - add support for Info-ZIP Unicode Path Extra Field PR #1181: RAR5 - fix merge_block() recursion (OSS-Fuzz 12999, 13029, 13144, 13478, 13490) PR #1183: fix memory leak when decompressing ZIP files with LZMA PR #1184: fix RAR5 OSS-Fuzz issues 12466, 14490, 14491, 12817 OSS-Fuzz 12466: RAR5 - fix buffer overflow when parsing huffman tables OSS-Fuzz 14490, 14491: RAR5 - fix bad shift-left operations OSS-Fuzz 12817: RAR5 - handle a case with truncated huffman tables PR #1186: RAR5 - fix invalid type used for dictionary size mask (OSS-Fuzz 14537) PR #1187: RAR5 - fix integer overflow (OSS-Fuzz 14555) PR #1190: RAR5 - RAR5 don't try to unpack entries marked as directories (OSS-Fuzz 14574) PR #1196: RAR5 - fix a potential SIGSEGV on 32-bit builds OSS-Fuzz 2582: RAR - fix use after free if there is an invalid entry OSS-Fuzz 14331: RAR5 - fix maximum owner name length OSS-Fuzz 13965: RAR5 - use unsigned int for volume number + range check Additional RAR5 reader changes: - support symlinks, hardlinks, file owner, file group, versioned files - change ARCHIVE_FORMAT_RAR_V5 to 0x100000 - set correct mode for readonly directories - support readonly, hidden and system Windows file attributes MFC after: 2 weeks
This commit is contained in:
commit
52c2bb7516
@ -1,3 +1,13 @@
|
||||
Apr 16, 2019: Support for non-recursive list and extract
|
||||
|
||||
Apr 14, 2019: New tar option: --exclude-vcs
|
||||
|
||||
Mar 27, 2019: Support for file and directory symlinks on Windows
|
||||
|
||||
Mar 12, 2019: Important fixes for storing file attributes and flags
|
||||
|
||||
Jan 20, 2019: Support for xz, lzma, ppmd8 and bzip2 compression in zip archives
|
||||
|
||||
Oct 06, 2018: RAR 5.0 reader
|
||||
|
||||
Sep 03, 2018: libarchive 3.3.3 released
|
||||
|
@ -46,7 +46,7 @@ verify_files(const char *msg)
|
||||
|
||||
/* Symlink */
|
||||
if (canSymlink())
|
||||
assertIsSymlink("symlink", "file");
|
||||
assertIsSymlink("symlink", "file", 0);
|
||||
|
||||
/* Another file with 1 link and different permissions. */
|
||||
failure(msg);
|
||||
@ -173,7 +173,7 @@ DEFINE_TEST(test_basic)
|
||||
|
||||
/* Symlink to above file. */
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("symlink", "file");
|
||||
assertMakeSymlink("symlink", "file", 0);
|
||||
fprintf(filelist, "symlink\n");
|
||||
if (is_LargeInode("symlink")) {
|
||||
strncat(result,
|
||||
|
@ -114,7 +114,7 @@ DEFINE_TEST(test_format_newc)
|
||||
|
||||
/* "symlink" */
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("symlink", "file1");
|
||||
assertMakeSymlink("symlink", "file1", 0);
|
||||
fprintf(list, "symlink\n");
|
||||
}
|
||||
|
||||
@ -233,7 +233,12 @@ DEFINE_TEST(test_format_newc)
|
||||
assert(is_hex(e, 110));
|
||||
assertEqualMem(e + 0, "070701", 6); /* Magic */
|
||||
assert(is_hex(e + 6, 8)); /* ino */
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
/* Mode: Group members bits and others bits do not work. */
|
||||
assertEqualInt(0xa180, from_hex(e + 14, 8) & 0xffc0);
|
||||
#else
|
||||
assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
|
||||
#endif
|
||||
assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
|
||||
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
|
||||
assertEqualMem(e + 38, "00000001", 8); /* nlink */
|
||||
|
@ -71,7 +71,7 @@ unpack_test(const char *from, const char *options, const char *se)
|
||||
|
||||
/* Symlink */
|
||||
if (canSymlink())
|
||||
assertIsSymlink("symlink", "file");
|
||||
assertIsSymlink("symlink", "file", 0);
|
||||
|
||||
/* dir */
|
||||
assertIsDir("dir", 0775);
|
||||
|
@ -30,8 +30,10 @@ __FBSDID("$FreeBSD$");
|
||||
* tests won't run on Windows. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#define CAT "type"
|
||||
#define SEP "\\"
|
||||
#else
|
||||
#define CAT "cat"
|
||||
#define SEP "/"
|
||||
#endif
|
||||
|
||||
DEFINE_TEST(test_option_L_upper)
|
||||
@ -51,7 +53,7 @@ DEFINE_TEST(test_option_L_upper)
|
||||
fprintf(filelist, "file\n");
|
||||
|
||||
/* Symlink to above file. */
|
||||
assertMakeSymlink("symlink", "file");
|
||||
assertMakeSymlink("symlink", "file", 0);
|
||||
fprintf(filelist, "symlink\n");
|
||||
|
||||
fclose(filelist);
|
||||
@ -61,7 +63,7 @@ DEFINE_TEST(test_option_L_upper)
|
||||
assertTextFileContents("1 block\n", "copy.err");
|
||||
|
||||
failure("Regular -p without -L should preserve symlinks.");
|
||||
assertIsSymlink("copy/symlink", NULL);
|
||||
assertIsSymlink("copy/symlink", NULL, 0);
|
||||
|
||||
r = systemf(CAT " filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
@ -77,13 +79,14 @@ DEFINE_TEST(test_option_L_upper)
|
||||
|
||||
assertMakeDir("unpack", 0755);
|
||||
assertChdir("unpack");
|
||||
r = systemf(CAT " ../archive.out | %s -i >unpack.out 2>unpack.err", testprog);
|
||||
r = systemf(CAT " .." SEP "archive.out | %s -i >unpack.out 2>unpack.err", testprog);
|
||||
|
||||
failure("Error invoking %s -i", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "unpack.err");
|
||||
assertChdir("..");
|
||||
|
||||
assertIsSymlink("unpack/symlink", NULL);
|
||||
assertIsSymlink("unpack/symlink", NULL, 0);
|
||||
|
||||
r = systemf(CAT " filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
|
||||
failure("Error invoking %s -oL", testprog);
|
||||
@ -92,7 +95,8 @@ DEFINE_TEST(test_option_L_upper)
|
||||
|
||||
assertMakeDir("unpack-L", 0755);
|
||||
assertChdir("unpack-L");
|
||||
r = systemf(CAT " ../archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
|
||||
r = systemf(CAT " .." SEP "archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
|
||||
|
||||
failure("Error invoking %s -i < archive-L.out", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "unpack-L.err");
|
||||
|
@ -71,8 +71,13 @@ test_create(void)
|
||||
* #ifdef this section out. Most of the test below is
|
||||
* still valid. */
|
||||
memset(×, 0, sizeof(times));
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
times.actime = 86400;
|
||||
times.modtime = 86400;
|
||||
#else
|
||||
times.actime = 1;
|
||||
times.modtime = 3;
|
||||
#endif
|
||||
assertEqualInt(0, utime(files[i].name, ×));
|
||||
|
||||
/* Record whatever atime the file ended up with. */
|
||||
|
@ -85,7 +85,7 @@ DEFINE_TEST(test_option_c)
|
||||
|
||||
/* "symlink" */
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("symlink", "file");
|
||||
assertMakeSymlink("symlink", "file", 0);
|
||||
fprintf(filelist, "symlink\n");
|
||||
}
|
||||
|
||||
|
@ -338,9 +338,9 @@ typedef const char *archive_passphrase_callback(struct archive *,
|
||||
#define ARCHIVE_FORMAT_LHA 0xB0000
|
||||
#define ARCHIVE_FORMAT_CAB 0xC0000
|
||||
#define ARCHIVE_FORMAT_RAR 0xD0000
|
||||
#define ARCHIVE_FORMAT_RAR_V5 (ARCHIVE_FORMAT_RAR | 1)
|
||||
#define ARCHIVE_FORMAT_7ZIP 0xE0000
|
||||
#define ARCHIVE_FORMAT_WARC 0xF0000
|
||||
#define ARCHIVE_FORMAT_RAR_V5 0x100000
|
||||
|
||||
/*
|
||||
* Codes returned by archive_read_format_capabilities().
|
||||
@ -1095,6 +1095,8 @@ __LA_DECL int archive_match_excluded(struct archive *,
|
||||
*/
|
||||
__LA_DECL int archive_match_path_excluded(struct archive *,
|
||||
struct archive_entry *);
|
||||
/* Control recursive inclusion of directory content when directory is included. Default on. */
|
||||
__LA_DECL int archive_match_set_inclusion_recursion(struct archive *, int);
|
||||
/* Add exclusion pathname pattern. */
|
||||
__LA_DECL int archive_match_exclude_pattern(struct archive *, const char *);
|
||||
__LA_DECL int archive_match_exclude_pattern_w(struct archive *,
|
||||
|
@ -168,6 +168,7 @@ archive_entry_clear(struct archive_entry *entry)
|
||||
archive_entry_xattr_clear(entry);
|
||||
archive_entry_sparse_clear(entry);
|
||||
free(entry->stat);
|
||||
entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
return entry;
|
||||
}
|
||||
@ -202,6 +203,9 @@ archive_entry_clone(struct archive_entry *entry)
|
||||
entry2->ae_set = entry->ae_set;
|
||||
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
|
||||
|
||||
/* Copy symlink type */
|
||||
entry2->ae_symlink_type = entry->ae_symlink_type;
|
||||
|
||||
/* Copy encryption status */
|
||||
entry2->encryption = entry->encryption;
|
||||
|
||||
@ -253,6 +257,7 @@ archive_entry_new2(struct archive *a)
|
||||
if (entry == NULL)
|
||||
return (NULL);
|
||||
entry->archive = a;
|
||||
entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
|
||||
return (entry);
|
||||
}
|
||||
|
||||
@ -675,6 +680,12 @@ archive_entry_symlink(struct archive_entry *entry)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_symlink_type(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->ae_symlink_type);
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_entry_symlink_utf8(struct archive_entry *entry)
|
||||
{
|
||||
@ -1245,6 +1256,12 @@ archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_symlink_type(struct archive_entry *entry, int type)
|
||||
{
|
||||
entry->ae_symlink_type = type;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
|
||||
{
|
||||
@ -1749,6 +1766,10 @@ static const struct flag {
|
||||
{ "nohidden", L"nohidden", UF_HIDDEN, 0},
|
||||
{ "nouhidden", L"nouhidden", UF_HIDDEN, 0},
|
||||
#endif
|
||||
#ifdef FILE_ATTRIBUTE_HIDDEN
|
||||
{ "nohidden", L"nohidden", FILE_ATTRIBUTE_HIDDEN, 0},
|
||||
{ "nouhidden", L"nouhidden", FILE_ATTRIBUTE_HIDDEN, 0},
|
||||
#endif
|
||||
#ifdef UF_OFFLINE
|
||||
{ "nooffline", L"nooffline", UF_OFFLINE, 0},
|
||||
{ "nouoffline", L"nouoffline", UF_OFFLINE, 0},
|
||||
@ -1758,6 +1779,11 @@ static const struct flag {
|
||||
{ "nourdonly", L"nourdonly", UF_READONLY, 0},
|
||||
{ "noreadonly", L"noreadonly", UF_READONLY, 0},
|
||||
#endif
|
||||
#ifdef FILE_ATTRIBUTE_READONLY
|
||||
{ "nordonly", L"nordonly", FILE_ATTRIBUTE_READONLY, 0},
|
||||
{ "nourdonly", L"nourdonly", FILE_ATTRIBUTE_READONLY, 0},
|
||||
{ "noreadonly", L"noreadonly", FILE_ATTRIBUTE_READONLY, 0},
|
||||
#endif
|
||||
#ifdef UF_SPARSE
|
||||
{ "nosparse", L"nosparse", UF_SPARSE, 0},
|
||||
{ "nousparse", L"nousparse", UF_SPARSE, 0},
|
||||
@ -1770,6 +1796,10 @@ static const struct flag {
|
||||
{ "nosystem", L"nosystem", UF_SYSTEM, 0},
|
||||
{ "nousystem", L"nousystem", UF_SYSTEM, 0},
|
||||
#endif
|
||||
#ifdef FILE_ATTRIBUTE_SYSTEM
|
||||
{ "nosystem", L"nosystem", FILE_ATTRIBUTE_SYSTEM, 0},
|
||||
{ "nousystem", L"nousystem", FILE_ATTRIBUTE_SYSTEM, 0},
|
||||
#endif
|
||||
#if defined(FS_UNRM_FL) /* 'u' */
|
||||
{ "noundel", L"noundel", FS_UNRM_FL, 0},
|
||||
#elif defined(EXT2_UNRM_FL)
|
||||
|
@ -190,6 +190,13 @@ struct archive_entry;
|
||||
#define AE_IFDIR ((__LA_MODE_T)0040000)
|
||||
#define AE_IFIFO ((__LA_MODE_T)0010000)
|
||||
|
||||
/*
|
||||
* Symlink types
|
||||
*/
|
||||
#define AE_SYMLINK_TYPE_UNDEFINED 0
|
||||
#define AE_SYMLINK_TYPE_FILE 1
|
||||
#define AE_SYMLINK_TYPE_DIRECTORY 2
|
||||
|
||||
/*
|
||||
* Basic object manipulation
|
||||
*/
|
||||
@ -275,6 +282,7 @@ __LA_DECL int archive_entry_size_is_set(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
|
||||
@ -350,6 +358,7 @@ __LA_DECL void archive_entry_unset_size(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_symlink_type(struct archive_entry *, int);
|
||||
__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
|
||||
@ -692,7 +701,6 @@ __LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
|
||||
struct archive_entry **, struct archive_entry **);
|
||||
__LA_DECL struct archive_entry *archive_entry_partial_links(
|
||||
struct archive_entry_linkresolver *res, unsigned int *links);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
62
contrib/libarchive/libarchive/archive_entry_misc.3
Normal file
62
contrib/libarchive/libarchive/archive_entry_misc.3
Normal file
@ -0,0 +1,62 @@
|
||||
.\" Copyright (c) 2019 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
.\"
|
||||
.Dd April 15, 2019
|
||||
.Dt ARCHIVE_ENTRY_MISC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_symlink_type ,
|
||||
.Nm archive_entry_set_symlink_type
|
||||
.Nd miscellaneous functions for manipulating properties of archive_entry.
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft int
|
||||
.Fn archive_entry_symlink_type "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_symlink_type "struct archive_entry *a" "int"
|
||||
.Sh DESCRIPTION
|
||||
The function
|
||||
.Fn archive_entry_symlink_type
|
||||
returns and the function
|
||||
.Fn archive_entry_set_symlink_type
|
||||
sets the type of the symbolic link stored in an archive entry. These functions
|
||||
have special meaning on operating systems that support multiple symbolic link
|
||||
types (e.g. Microsoft Windows).
|
||||
.Pp
|
||||
Supported values are:
|
||||
.Bl -tag -width "AE_SYMLINK_TYPE_DIRECTORY" -compact
|
||||
.It AE_SYMLINK_TYPE_UNDEFINED
|
||||
Symbolic link target type is not defined (default on unix systems)
|
||||
.It AE_SYMLINK_TYPE_FILE
|
||||
Symbolic link points to a file
|
||||
.It AE_SYMLINK_TYPE_DIRECTORY
|
||||
Symbolic link points to a directory
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr archive_entry_paths 3 ,
|
||||
.Xr archive_entry_stat 3 ,
|
||||
.Xr libarchive 3
|
@ -176,6 +176,9 @@ struct archive_entry {
|
||||
|
||||
/* Miscellaneous. */
|
||||
char strmode[12];
|
||||
|
||||
/* Symlink type support */
|
||||
int ae_symlink_type;
|
||||
};
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
||||
|
@ -83,6 +83,7 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
BCRYPT_HASH_HANDLE hHash;
|
||||
DWORD hash_len;
|
||||
|
@ -93,6 +93,9 @@ struct archive_match {
|
||||
/* exclusion/inclusion set flag. */
|
||||
int setflag;
|
||||
|
||||
/* Recursively include directory content? */
|
||||
int recursive_include;
|
||||
|
||||
/*
|
||||
* Matching filename patterns.
|
||||
*/
|
||||
@ -223,6 +226,7 @@ archive_match_new(void)
|
||||
return (NULL);
|
||||
a->archive.magic = ARCHIVE_MATCH_MAGIC;
|
||||
a->archive.state = ARCHIVE_STATE_NEW;
|
||||
a->recursive_include = 1;
|
||||
match_list_init(&(a->inclusions));
|
||||
match_list_init(&(a->exclusions));
|
||||
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
|
||||
@ -470,6 +474,28 @@ archive_match_path_excluded(struct archive *_a,
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* When recursive inclusion of directory content is enabled,
|
||||
* an inclusion pattern that matches a directory will also
|
||||
* include everything beneath that directory. Enabled by default.
|
||||
*
|
||||
* For compatibility with GNU tar, exclusion patterns always
|
||||
* match if a subset of the full patch matches (i.e., they are
|
||||
* are not rooted at the beginning of the path) and thus there
|
||||
* is no corresponding non-recursive exclusion mode.
|
||||
*/
|
||||
int
|
||||
archive_match_set_inclusion_recursion(struct archive *_a, int enabled)
|
||||
{
|
||||
struct archive_match *a;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_match_set_inclusion_recursion");
|
||||
a = (struct archive_match *)_a;
|
||||
a->recursive_include = enabled;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility functions to get statistic information for inclusion patterns.
|
||||
*/
|
||||
@ -781,7 +807,10 @@ static int
|
||||
match_path_inclusion(struct archive_match *a, struct match *m,
|
||||
int mbs, const void *pn)
|
||||
{
|
||||
int flag = PATHMATCH_NO_ANCHOR_END;
|
||||
/* Recursive operation requires only a prefix match. */
|
||||
int flag = a->recursive_include ?
|
||||
PATHMATCH_NO_ANCHOR_END :
|
||||
0;
|
||||
int r;
|
||||
|
||||
if (mbs) {
|
||||
@ -1232,7 +1261,7 @@ set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
|
||||
archive_set_error(&(a->archive), EINVAL, "pathname is empty");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (stat(path, &st) != 0) {
|
||||
if (la_stat(path, &st) != 0) {
|
||||
archive_set_error(&(a->archive), errno, "Failed to stat()");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
@ -69,6 +69,8 @@
|
||||
* either Windows or Posix APIs. */
|
||||
#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
|
||||
#include "archive_windows.h"
|
||||
#else
|
||||
#define la_stat(path,stref) stat(path,stref)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -611,6 +611,15 @@ choose_filters(struct archive_read *a)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
int
|
||||
__archive_read_header(struct archive_read *a, struct archive_entry *entry)
|
||||
{
|
||||
if (a->filter->read_header)
|
||||
return a->filter->read_header(a->filter, entry);
|
||||
else
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read header of next entry.
|
||||
*/
|
||||
|
@ -191,7 +191,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (stat(path, &s) != 0) {
|
||||
if (la_stat(path, &s) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't stat %s", path);
|
||||
return (ARCHIVE_FAILED);
|
||||
|
@ -909,7 +909,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (lst == NULL);
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -1295,10 +1295,23 @@ archive_read_disk_descend(struct archive *_a)
|
||||
if (t->visit_type != TREE_REGULAR || !t->descend)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
/*
|
||||
* We must not treat the initial specified path as a physical dir,
|
||||
* because if we do then we will try and ascend out of it by opening
|
||||
* ".." which is (a) wrong and (b) causes spurious permissions errors
|
||||
* if ".." is not readable by us. Instead, treat it as if it were a
|
||||
* symlink. (This uses an extra fd, but it can only happen once at the
|
||||
* top level of a traverse.) But we can't necessarily assume t->st is
|
||||
* valid here (though t->lst is), which complicates the logic a
|
||||
* little.
|
||||
*/
|
||||
if (tree_current_is_physical_dir(t)) {
|
||||
tree_push(t, t->basename, t->current_filesystem_id,
|
||||
t->lst.st_dev, t->lst.st_ino, &t->restore_time);
|
||||
t->stack->flags |= isDir;
|
||||
if (t->stack->parent->parent != NULL)
|
||||
t->stack->flags |= isDir;
|
||||
else
|
||||
t->stack->flags |= isDirLink;
|
||||
} else if (tree_current_is_dir(t)) {
|
||||
tree_push(t, t->basename, t->current_filesystem_id,
|
||||
t->st.st_dev, t->st.st_ino, &t->restore_time);
|
||||
@ -2151,6 +2164,17 @@ tree_open(const char *path, int symlink_mode, int restore_time)
|
||||
static struct tree *
|
||||
tree_reopen(struct tree *t, const char *path, int restore_time)
|
||||
{
|
||||
#if defined(O_PATH)
|
||||
/* Linux */
|
||||
const int o_flag = O_PATH;
|
||||
#elif defined(O_SEARCH)
|
||||
/* SunOS */
|
||||
const int o_flag = O_SEARCH;
|
||||
#elif defined(O_EXEC)
|
||||
/* FreeBSD */
|
||||
const int o_flag = O_EXEC;
|
||||
#endif
|
||||
|
||||
t->flags = (restore_time != 0)?needsRestoreTimes:0;
|
||||
t->flags |= onInitialDir;
|
||||
t->visit_type = 0;
|
||||
@ -2172,6 +2196,15 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
|
||||
t->stack->flags = needsFirstVisit;
|
||||
t->maxOpenCount = t->openCount = 1;
|
||||
t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
|
||||
#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC)
|
||||
/*
|
||||
* Most likely reason to fail opening "." is that it's not readable,
|
||||
* so try again for execute. The consequences of not opening this are
|
||||
* unhelpful and unnecessary errors later.
|
||||
*/
|
||||
if (t->initial_dir_fd < 0)
|
||||
t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
|
||||
#endif
|
||||
__archive_ensure_cloexec_flag(t->initial_dir_fd);
|
||||
t->working_dir_fd = tree_dup(t->initial_dir_fd);
|
||||
return (t);
|
||||
@ -2479,7 +2512,7 @@ tree_current_stat(struct tree *t)
|
||||
#else
|
||||
if (tree_enter_working_dir(t) != 0)
|
||||
return NULL;
|
||||
if (stat(tree_current_access_path(t), &t->st) != 0)
|
||||
if (la_stat(tree_current_access_path(t), &t->st) != 0)
|
||||
#endif
|
||||
return NULL;
|
||||
t->flags |= hasStat;
|
||||
|
@ -98,6 +98,8 @@ struct archive_read_filter {
|
||||
int (*close)(struct archive_read_filter *self);
|
||||
/* Function that handles switching from reading one block to the next/prev */
|
||||
int (*sswitch)(struct archive_read_filter *self, unsigned int iindex);
|
||||
/* Read any header metadata if available. */
|
||||
int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry);
|
||||
/* My private data. */
|
||||
void *data;
|
||||
|
||||
@ -250,6 +252,7 @@ int64_t __archive_read_seek(struct archive_read*, int64_t, int);
|
||||
int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
|
||||
int64_t __archive_read_consume(struct archive_read *, int64_t);
|
||||
int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
|
||||
int __archive_read_header(struct archive_read *, struct archive_entry *);
|
||||
int __archive_read_program(struct archive_read_filter *, const char *);
|
||||
void __archive_read_free_filters(struct archive_read *);
|
||||
struct archive_read_extract *__archive_read_get_extract(struct archive_read *);
|
||||
|
@ -73,6 +73,9 @@ archive_read_set_format(struct archive *_a, int code)
|
||||
case ARCHIVE_FORMAT_RAR:
|
||||
strcpy(str, "rar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
strcpy(str, "rar5");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
strcpy(str, "tar");
|
||||
break;
|
||||
|
@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@ -45,6 +48,8 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_endian.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
@ -56,6 +61,8 @@ struct private_data {
|
||||
size_t out_block_size;
|
||||
int64_t total_out;
|
||||
unsigned long crc;
|
||||
uint32_t mtime;
|
||||
char *name;
|
||||
char eof; /* True = found end of compressed data. */
|
||||
};
|
||||
|
||||
@ -123,7 +130,8 @@ archive_read_support_filter_gzip(struct archive *_a)
|
||||
* count of bits verified, suitable for use by bidder.
|
||||
*/
|
||||
static ssize_t
|
||||
peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
peek_at_header(struct archive_read_filter *filter, int *pbits,
|
||||
struct private_data *state)
|
||||
{
|
||||
const unsigned char *p;
|
||||
ssize_t avail, len;
|
||||
@ -144,7 +152,9 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
return (0);
|
||||
bits += 3;
|
||||
header_flags = p[3];
|
||||
/* Bytes 4-7 are mod time. */
|
||||
/* Bytes 4-7 are mod time in little endian. */
|
||||
if (state)
|
||||
state->mtime = archive_le32dec(p + 4);
|
||||
/* Byte 8 is deflate flags. */
|
||||
/* XXXX TODO: return deflate flags back to consume_header for use
|
||||
in initializing the decompressor. */
|
||||
@ -161,6 +171,7 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
|
||||
/* Null-terminated optional filename. */
|
||||
if (header_flags & 8) {
|
||||
ssize_t file_start = len;
|
||||
do {
|
||||
++len;
|
||||
if (avail < len)
|
||||
@ -169,6 +180,12 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
if (p == NULL)
|
||||
return (0);
|
||||
} while (p[len - 1] != 0);
|
||||
|
||||
if (state) {
|
||||
/* Reset the name in case of repeat header reads. */
|
||||
free(state->name);
|
||||
state->name = strdup((const char *)&p[file_start]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Null-terminated optional comment. */
|
||||
@ -214,11 +231,28 @@ gzip_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
|
||||
if (peek_at_header(filter, &bits_checked))
|
||||
if (peek_at_header(filter, &bits_checked, NULL))
|
||||
return (bits_checked);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
gzip_read_header(struct archive_read_filter *self, struct archive_entry *entry)
|
||||
{
|
||||
struct private_data *state;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
/* A mtime of 0 is considered invalid/missing. */
|
||||
if (state->mtime != 0)
|
||||
archive_entry_set_mtime(entry, state->mtime, 0);
|
||||
|
||||
/* If the name is available, extract it. */
|
||||
if (state->name)
|
||||
archive_entry_set_pathname(entry, state->name);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#ifndef HAVE_ZLIB_H
|
||||
|
||||
@ -272,6 +306,7 @@ gzip_bidder_init(struct archive_read_filter *self)
|
||||
self->read = gzip_filter_read;
|
||||
self->skip = NULL; /* not supported */
|
||||
self->close = gzip_filter_close;
|
||||
self->read_header = gzip_read_header;
|
||||
|
||||
state->in_stream = 0; /* We're not actually within a stream yet. */
|
||||
|
||||
@ -289,7 +324,7 @@ consume_header(struct archive_read_filter *self)
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
/* If this is a real header, consume it. */
|
||||
len = peek_at_header(self->upstream, NULL);
|
||||
len = peek_at_header(self->upstream, NULL, state);
|
||||
if (len == 0)
|
||||
return (ARCHIVE_EOF);
|
||||
__archive_read_filter_consume(self->upstream, len);
|
||||
@ -374,7 +409,7 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
|
||||
{
|
||||
struct private_data *state;
|
||||
size_t decompressed;
|
||||
ssize_t avail_in;
|
||||
ssize_t avail_in, max_in;
|
||||
int ret;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
@ -408,6 +443,12 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
|
||||
"truncated gzip input");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (UINT_MAX >= SSIZE_MAX)
|
||||
max_in = SSIZE_MAX;
|
||||
else
|
||||
max_in = UINT_MAX;
|
||||
if (avail_in > max_in)
|
||||
avail_in = max_in;
|
||||
state->stream.avail_in = (uInt)avail_in;
|
||||
|
||||
/* Decompress and consume some of that data. */
|
||||
@ -469,6 +510,7 @@ gzip_filter_close(struct archive_read_filter *self)
|
||||
}
|
||||
}
|
||||
|
||||
free(state->name);
|
||||
free(state->out_block);
|
||||
free(state);
|
||||
return (ret);
|
||||
|
@ -1509,8 +1509,8 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
|
||||
}
|
||||
if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
|
||||
goto nomszip;
|
||||
else if (cab->stream.next_in[0] != 0x43 ||
|
||||
cab->stream.next_in[1] != 0x4b)
|
||||
else if (mszip == 2 && (cab->stream.next_in[0] != 0x43 ||
|
||||
cab->stream.next_in[1] != 0x4b))
|
||||
goto nomszip;
|
||||
cab->stream.next_in += mszip;
|
||||
cab->stream.avail_in -= mszip;
|
||||
|
@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
@ -1011,7 +1014,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
{
|
||||
ssize_t len;
|
||||
uintmax_t counter;
|
||||
char *p;
|
||||
char *p, *s;
|
||||
struct mtree_option *global;
|
||||
struct mtree_entry *last_entry;
|
||||
int r, is_form_d;
|
||||
@ -1025,6 +1028,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
(void)detect_form(a, &is_form_d);
|
||||
|
||||
for (counter = 1; ; ++counter) {
|
||||
r = ARCHIVE_OK;
|
||||
len = readline(a, mtree, &p, 65536);
|
||||
if (len == 0) {
|
||||
mtree->this_entry = mtree->entries;
|
||||
@ -1045,6 +1049,15 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
continue;
|
||||
if (*p == '\r' || *p == '\n' || *p == '\0')
|
||||
continue;
|
||||
/* Non-printable characters are not allowed */
|
||||
for (s = p;s < p + len - 1; s++) {
|
||||
if (!isprint(*s)) {
|
||||
r = ARCHIVE_FATAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r != ARCHIVE_OK)
|
||||
break;
|
||||
if (*p != '/') {
|
||||
r = process_add_entry(a, mtree, &global, p, len,
|
||||
&last_entry, is_form_d);
|
||||
|
@ -1024,8 +1024,10 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||
case COMPRESS_METHOD_GOOD:
|
||||
case COMPRESS_METHOD_BEST:
|
||||
ret = read_data_compressed(a, buff, size, offset);
|
||||
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
|
||||
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
rar->start_new_table = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -120,7 +120,9 @@ archive_read_format_raw_read_header(struct archive_read *a,
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_perm(entry, 0644);
|
||||
/* I'm deliberately leaving most fields unset here. */
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
/* Let the filter fill out any fields it might have. */
|
||||
return __archive_read_header(a, entry);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -694,11 +694,13 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
struct archive_entry *entry, size_t *unconsumed)
|
||||
{
|
||||
ssize_t bytes;
|
||||
int err;
|
||||
int err, eof_vol_header;
|
||||
const char *h;
|
||||
const struct archive_entry_header_ustar *header;
|
||||
const struct archive_entry_header_gnutar *gnuheader;
|
||||
|
||||
eof_vol_header = 0;
|
||||
|
||||
/* Loop until we find a workable header record. */
|
||||
for (;;) {
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
@ -788,6 +790,8 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
break;
|
||||
case 'V': /* GNU volume header */
|
||||
err = header_volume(a, tar, entry, h, unconsumed);
|
||||
if (err == ARCHIVE_EOF)
|
||||
eof_vol_header = 1;
|
||||
break;
|
||||
case 'X': /* Used by SUN tar; same as 'x'. */
|
||||
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
||||
@ -862,9 +866,17 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
if (err == ARCHIVE_EOF)
|
||||
/* EOF when recursively reading a header is bad. */
|
||||
archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
|
||||
if (err == ARCHIVE_EOF) {
|
||||
if (!eof_vol_header) {
|
||||
/* EOF when recursively reading a header is bad. */
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Damaged tar archive");
|
||||
} else {
|
||||
/* If we encounter just a GNU volume header treat
|
||||
* this situation as an empty archive */
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
}
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
@ -1944,6 +1956,15 @@ pax_attribute(struct archive_read *a, struct tar *tar,
|
||||
pax_time(value, &s, &n);
|
||||
archive_entry_set_birthtime(entry, s, n);
|
||||
}
|
||||
if (strcmp(key, "LIBARCHIVE.symlinktype") == 0) {
|
||||
if (strcmp(value, "file") == 0) {
|
||||
archive_entry_set_symlink_type(entry,
|
||||
AE_SYMLINK_TYPE_FILE);
|
||||
} else if (strcmp(value, "dir") == 0) {
|
||||
archive_entry_set_symlink_type(entry,
|
||||
AE_SYMLINK_TYPE_DIRECTORY);
|
||||
}
|
||||
}
|
||||
if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
|
||||
pax_attribute_xattr(entry, key, value);
|
||||
break;
|
||||
|
@ -744,8 +744,9 @@ _warc_rdlen(const char *buf, size_t bsz)
|
||||
/* there must be at least one digit */
|
||||
if (!isdigit((unsigned char)*val))
|
||||
return -1;
|
||||
errno = 0;
|
||||
len = strtol(val, &on, 10);
|
||||
if (on != eol) {
|
||||
if (errno != 0 || on != eol) {
|
||||
/* line must end here */
|
||||
return -1;
|
||||
}
|
||||
|
@ -798,7 +798,8 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
|
||||
xattr = file->xattr_list;
|
||||
while (xattr != NULL) {
|
||||
const void *d;
|
||||
size_t outbytes, used;
|
||||
size_t outbytes = 0;
|
||||
size_t used = 0;
|
||||
|
||||
r = move_reading_point(a, xattr->offset);
|
||||
if (r != ARCHIVE_OK)
|
||||
@ -820,8 +821,18 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
|
||||
r = checksum_final(a,
|
||||
xattr->a_sum.val, xattr->a_sum.len,
|
||||
xattr->e_sum.val, xattr->e_sum.len);
|
||||
if (r != ARCHIVE_OK)
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
||||
"Xattr checksum error");
|
||||
r = ARCHIVE_WARN;
|
||||
break;
|
||||
}
|
||||
if (xattr->name.s == NULL) {
|
||||
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
||||
"Xattr name error");
|
||||
r = ARCHIVE_WARN;
|
||||
break;
|
||||
}
|
||||
archive_entry_xattr_add_entry(entry,
|
||||
xattr->name.s, d, outbytes);
|
||||
xattr = xattr->next;
|
||||
@ -847,7 +858,7 @@ xar_read_data(struct archive_read *a,
|
||||
const void **buff, size_t *size, int64_t *offset)
|
||||
{
|
||||
struct xar *xar;
|
||||
size_t used;
|
||||
size_t used = 0;
|
||||
int r;
|
||||
|
||||
xar = (struct xar *)(a->format->data);
|
||||
|
@ -472,27 +472,49 @@ zip_time(const char *p)
|
||||
* triplets. id and size are 2 bytes each.
|
||||
*/
|
||||
static int
|
||||
process_extra(struct archive_read *a, const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
||||
process_extra(struct archive_read *a, struct archive_entry *entry,
|
||||
const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
||||
{
|
||||
unsigned offset = 0;
|
||||
struct zip *zip = (struct zip *)(a->format->data);
|
||||
|
||||
if (extra_length == 0) {
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
if (extra_length < 4) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Too-small extra data: Need at least 4 bytes, but only found %d bytes", (int)extra_length);
|
||||
return ARCHIVE_FAILED;
|
||||
size_t i = 0;
|
||||
/* Some ZIP files may have trailing 0 bytes. Let's check they
|
||||
* are all 0 and ignore them instead of returning an error.
|
||||
*
|
||||
* This is not techincally correct, but some ZIP files look
|
||||
* like this and other tools support those files - so let's
|
||||
* also support them.
|
||||
*/
|
||||
for (; i < extra_length; i++) {
|
||||
if (p[i] != 0) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Too-small extra data: "
|
||||
"Need at least 4 bytes, "
|
||||
"but only found %d bytes",
|
||||
(int)extra_length);
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
while (offset <= extra_length - 4) {
|
||||
unsigned short headerid = archive_le16dec(p + offset);
|
||||
unsigned short datasize = archive_le16dec(p + offset + 2);
|
||||
|
||||
offset += 4;
|
||||
if (offset + datasize > extra_length) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Extra data overflow: Need %d bytes but only found %d bytes",
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT, "Extra data overflow: "
|
||||
"Need %d bytes but only found %d bytes",
|
||||
(int)datasize, (int)(extra_length - offset));
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
@ -507,9 +529,12 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
if (zip_entry->uncompressed_size == 0xffffffff) {
|
||||
uint64_t t = 0;
|
||||
if (datasize < 8
|
||||
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit uncompressed size");
|
||||
|| (t = archive_le64dec(p + offset)) >
|
||||
INT64_MAX) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit "
|
||||
"uncompressed size");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
zip_entry->uncompressed_size = t;
|
||||
@ -519,9 +544,12 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
if (zip_entry->compressed_size == 0xffffffff) {
|
||||
uint64_t t = 0;
|
||||
if (datasize < 8
|
||||
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit compressed size");
|
||||
|| (t = archive_le64dec(p + offset)) >
|
||||
INT64_MAX) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit "
|
||||
"compressed size");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
zip_entry->compressed_size = t;
|
||||
@ -531,9 +559,12 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
if (zip_entry->local_header_offset == 0xffffffff) {
|
||||
uint64_t t = 0;
|
||||
if (datasize < 8
|
||||
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit local header offset");
|
||||
|| (t = archive_le64dec(p + offset)) >
|
||||
INT64_MAX) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit "
|
||||
"local header offset");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
zip_entry->local_header_offset = t;
|
||||
@ -566,7 +597,8 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
/* Extended time field "UT". */
|
||||
int flags;
|
||||
if (datasize == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Incomplete extended time field");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
@ -648,7 +680,8 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
* if bitmap & 1, 2 byte "version made by"
|
||||
* if bitmap & 2, 2 byte "internal file attributes"
|
||||
* if bitmap & 4, 4 byte "external file attributes"
|
||||
* if bitmap & 8, 2 byte comment length + n byte comment
|
||||
* if bitmap & 8, 2 byte comment length + n byte
|
||||
* comment
|
||||
*/
|
||||
int bitmap, bitmap_last;
|
||||
|
||||
@ -699,13 +732,18 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
= external_attributes >> 16;
|
||||
} else if (zip_entry->system == 0) {
|
||||
// Interpret MSDOS directory bit
|
||||
if (0x10 == (external_attributes & 0x10)) {
|
||||
zip_entry->mode = AE_IFDIR | 0775;
|
||||
if (0x10 == (external_attributes &
|
||||
0x10)) {
|
||||
zip_entry->mode =
|
||||
AE_IFDIR | 0775;
|
||||
} else {
|
||||
zip_entry->mode = AE_IFREG | 0664;
|
||||
zip_entry->mode =
|
||||
AE_IFREG | 0664;
|
||||
}
|
||||
if (0x01 == (external_attributes & 0x01)) {
|
||||
// Read-only bit; strip write permissions
|
||||
if (0x01 == (external_attributes &
|
||||
0x01)) {
|
||||
/* Read-only bit;
|
||||
* strip write permissions */
|
||||
zip_entry->mode &= 0555;
|
||||
}
|
||||
} else {
|
||||
@ -732,6 +770,59 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x7075:
|
||||
{
|
||||
/* Info-ZIP Unicode Path Extra Field. */
|
||||
if (datasize < 5 || entry == NULL)
|
||||
break;
|
||||
offset += 5;
|
||||
datasize -= 5;
|
||||
|
||||
/* The path name in this field is always encoded
|
||||
* in UTF-8. */
|
||||
if (zip->sconv_utf8 == NULL) {
|
||||
zip->sconv_utf8 =
|
||||
archive_string_conversion_from_charset(
|
||||
&a->archive, "UTF-8", 1);
|
||||
/* If the converter from UTF-8 is not
|
||||
* available, then the path name from the main
|
||||
* field will more likely be correct. */
|
||||
if (zip->sconv_utf8 == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure the CRC32 of the filename matches. */
|
||||
if (!zip->ignore_crc32) {
|
||||
const char *cp = archive_entry_pathname(entry);
|
||||
if (cp) {
|
||||
unsigned long file_crc =
|
||||
zip->crc32func(0, cp, strlen(cp));
|
||||
unsigned long utf_crc =
|
||||
archive_le32dec(p + offset - 4);
|
||||
if (file_crc != utf_crc) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"CRC filename mismatch; "
|
||||
"CDE is %lx, but UTF8 "
|
||||
"is outdated with %lx\n",
|
||||
file_crc, utf_crc);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (archive_entry_copy_pathname_l(entry,
|
||||
p + offset, datasize, zip->sconv_utf8) != 0) {
|
||||
/* Ignore the error, and fallback to the path
|
||||
* name from the main field. */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Failed to read the ZIP "
|
||||
"0x7075 extra field path.\n");
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x7855:
|
||||
/* Info-ZIP Unix Extra Field (type 2) "Ux". */
|
||||
#ifdef DEBUG
|
||||
@ -766,7 +857,8 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
}
|
||||
if (datasize >= (2 + uidsize + 3)) {
|
||||
/* get a gid size. */
|
||||
gidsize = 0xff & (int)p[offset+2+uidsize];
|
||||
gidsize = 0xff &
|
||||
(int)p[offset+2+uidsize];
|
||||
if (gidsize == 2)
|
||||
zip_entry->gid =
|
||||
archive_le16dec(
|
||||
@ -783,7 +875,8 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
case 0x9901:
|
||||
/* WinZip AES extra data field. */
|
||||
if (datasize < 6) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Incomplete AES field");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
@ -803,12 +896,6 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
}
|
||||
offset += datasize;
|
||||
}
|
||||
if (offset != extra_length) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed extra data: Consumed %d bytes of %d bytes",
|
||||
(int)offset, (int)extra_length);
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
@ -928,7 +1015,8 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if (ARCHIVE_OK != process_extra(a, h, extra_length, zip_entry)) {
|
||||
if (ARCHIVE_OK != process_extra(a, entry, h, extra_length,
|
||||
zip_entry)) {
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
__archive_read_consume(a, extra_length);
|
||||
@ -945,8 +1033,8 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
zip_entry->mode |= 0664;
|
||||
}
|
||||
|
||||
/* Windows archivers sometimes use backslash as the directory separator.
|
||||
Normalize to slash. */
|
||||
/* Windows archivers sometimes use backslash as the directory
|
||||
* separator. Normalize to slash. */
|
||||
if (zip_entry->system == 0 &&
|
||||
(wp = archive_entry_pathname_w(entry)) != NULL) {
|
||||
if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) {
|
||||
@ -1255,7 +1343,8 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
|
||||
zip->entry->crc32 = archive_le32dec(p + 4);
|
||||
compressed = archive_le64dec(p + 8);
|
||||
uncompressed = archive_le64dec(p + 16);
|
||||
if (compressed > INT64_MAX || uncompressed > INT64_MAX) {
|
||||
if (compressed > INT64_MAX || uncompressed >
|
||||
INT64_MAX) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Overflow of 64-bit file sizes");
|
||||
@ -1372,7 +1461,8 @@ consume_optional_marker(struct archive_read *a, struct zip *zip)
|
||||
zip->entry->crc32 = archive_le32dec(p);
|
||||
compressed = archive_le64dec(p + 4);
|
||||
uncompressed = archive_le64dec(p + 12);
|
||||
if (compressed > INT64_MAX || uncompressed > INT64_MAX) {
|
||||
if (compressed > INT64_MAX ||
|
||||
uncompressed > INT64_MAX) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Overflow of 64-bit file sizes");
|
||||
@ -1444,12 +1534,16 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
|
||||
} alone_header;
|
||||
#pragma pack(pop)
|
||||
|
||||
/* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma that
|
||||
* is a part of XZ Utils. The stream format stored inside ZIPX file is a
|
||||
* modified "lzma alone" file format, that was used by the `lzma` utility
|
||||
* which was later deprecated in favour of `xz` utility. Since those
|
||||
* formats are nearly the same, we can use a standard "lzma alone" decoder
|
||||
* from XZ Utils. */
|
||||
if(zip->zipx_lzma_valid) {
|
||||
lzma_end(&zip->zipx_lzma_stream);
|
||||
zip->zipx_lzma_valid = 0;
|
||||
}
|
||||
|
||||
/* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma
|
||||
* that is a part of XZ Utils. The stream format stored inside ZIPX
|
||||
* file is a modified "lzma alone" file format, that was used by the
|
||||
* `lzma` utility which was later deprecated in favour of `xz` utility. * Since those formats are nearly the same, we can use a standard
|
||||
* "lzma alone" decoder from XZ Utils. */
|
||||
|
||||
memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
|
||||
r = lzma_alone_decoder(&zip->zipx_lzma_stream, UINT64_MAX);
|
||||
@ -1477,8 +1571,8 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
|
||||
* lzma_params is a 5-byte blob that has to be decoded to extract
|
||||
* parameters of this LZMA stream. The uncompressed_size field is an
|
||||
* uint64_t value that contains information about the size of the
|
||||
* uncompressed file, or UINT64_MAX if this value is unknown. The <data...>
|
||||
* part is the actual lzma-compressed data stream.
|
||||
* uncompressed file, or UINT64_MAX if this value is unknown.
|
||||
* The <data...> part is the actual lzma-compressed data stream.
|
||||
*
|
||||
* Now here's the structure of the stream inside the ZIPX file:
|
||||
*
|
||||
@ -1488,17 +1582,17 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
|
||||
* 2byte 2byte 5 bytes n bytes
|
||||
* <magic1><magic2><lzma_params><data...>
|
||||
*
|
||||
* This means that the ZIPX file contains an additional magic1 and magic2
|
||||
* headers, the lzma_params field contains the same parameter set as in the
|
||||
* "lzma alone" format, and the <data...> field is the same as in the "lzma
|
||||
* alone" format as well. Note that also the zipx format is missing the
|
||||
* uncompressed_size field.
|
||||
* This means that the ZIPX file contains an additional magic1 and
|
||||
* magic2 headers, the lzma_params field contains the same parameter
|
||||
* set as in the "lzma alone" format, and the <data...> field is the
|
||||
* same as in the "lzma alone" format as well. Note that also the zipx
|
||||
* format is missing the uncompressed_size field.
|
||||
*
|
||||
* So, in order to use the "lzma alone" decoder for the zipx lzma stream,
|
||||
* we simply need to shuffle around some fields, prepare a new lzma alone
|
||||
* header, feed it into lzma alone decoder so it will initialize itself
|
||||
* properly, and then we can start feeding normal zipx lzma stream into the
|
||||
* decoder.
|
||||
* So, in order to use the "lzma alone" decoder for the zipx lzma
|
||||
* stream, we simply need to shuffle around some fields, prepare a new
|
||||
* lzma alone header, feed it into lzma alone decoder so it will
|
||||
* initialize itself properly, and then we can start feeding normal
|
||||
* zipx lzma stream into the decoder.
|
||||
*/
|
||||
|
||||
/* Read magic1,magic2,lzma_params from the ZIPX stream. */
|
||||
@ -1514,8 +1608,8 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Prepare an lzma alone header: copy the lzma_params blob into a proper
|
||||
* place into the lzma alone header. */
|
||||
/* Prepare an lzma alone header: copy the lzma_params blob into
|
||||
* a proper place into the lzma alone header. */
|
||||
memcpy(&alone_header.bytes[0], p + 4, 5);
|
||||
|
||||
/* Initialize the 'uncompressed size' field to unknown; we'll manually
|
||||
@ -1541,8 +1635,9 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
|
||||
zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size;
|
||||
zip->zipx_lzma_stream.total_out = 0;
|
||||
|
||||
/* Feed only the header into the lzma alone decoder. This will effectively
|
||||
* initialize the decoder, and will not produce any output bytes yet. */
|
||||
/* Feed only the header into the lzma alone decoder. This will
|
||||
* effectively initialize the decoder, and will not produce any
|
||||
* output bytes yet. */
|
||||
r = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
|
||||
if (r != LZMA_OK) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
@ -1617,7 +1712,8 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
|
||||
if((int64_t) zip->zipx_lzma_stream.total_in !=
|
||||
zip->entry_bytes_remaining)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"xz premature end of stream");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
@ -1662,12 +1758,13 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Fetch more compressed data. The same note as in deflate handler applies
|
||||
* here as well:
|
||||
/* Fetch more compressed data. The same note as in deflate handler
|
||||
* applies here as well:
|
||||
*
|
||||
* Note: '1' here is a performance optimization. Recall that the
|
||||
* decompression layer returns a count of available bytes; asking for more
|
||||
* than that forces the decompressor to combine reads by copying data.
|
||||
* decompression layer returns a count of available bytes; asking for
|
||||
* more than that forces the decompressor to combine reads by copying
|
||||
* data.
|
||||
*/
|
||||
compressed_buf = __archive_read_ahead(a, 1, &bytes_avail);
|
||||
if (bytes_avail < 0) {
|
||||
@ -1684,8 +1781,9 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
|
||||
zip->zipx_lzma_stream.total_in = 0;
|
||||
zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
|
||||
zip->zipx_lzma_stream.avail_out =
|
||||
/* These lzma_alone streams lack end of stream marker, so let's make
|
||||
* sure the unpacker won't try to unpack more than it's supposed to. */
|
||||
/* These lzma_alone streams lack end of stream marker, so let's
|
||||
* make sure the unpacker won't try to unpack more than it's
|
||||
* supposed to. */
|
||||
zipmin((int64_t) zip->uncompressed_buffer_size,
|
||||
zip->entry->uncompressed_size -
|
||||
zip->entry_uncompressed_bytes_read);
|
||||
@ -1810,7 +1908,8 @@ zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
__archive_ppmd8_functions.Ppmd8_Init(&zip->ppmd8, order, restore_method);
|
||||
__archive_ppmd8_functions.Ppmd8_Init(&zip->ppmd8, order,
|
||||
restore_method);
|
||||
|
||||
/* Allocate the buffer that will hold uncompressed data. */
|
||||
free(zip->uncompressed_buffer);
|
||||
@ -1856,8 +1955,8 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Fetch for more data. We're reading 1 byte here, but libarchive should
|
||||
* prefetch more bytes. */
|
||||
/* Fetch for more data. We're reading 1 byte here, but libarchive
|
||||
* should prefetch more bytes. */
|
||||
(void) __archive_read_ahead(a, 1, &bytes_avail);
|
||||
if(bytes_avail < 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -1871,7 +1970,8 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
|
||||
|
||||
/* Decompression loop. */
|
||||
do {
|
||||
int sym = __archive_ppmd8_functions.Ppmd8_DecodeSymbol(&zip->ppmd8);
|
||||
int sym = __archive_ppmd8_functions.Ppmd8_DecodeSymbol(
|
||||
&zip->ppmd8);
|
||||
if(sym < 0) {
|
||||
zip->end_of_entry = 1;
|
||||
break;
|
||||
@ -1880,8 +1980,9 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
|
||||
/* This field is set by ppmd_read() when there was no more data
|
||||
* to be read. */
|
||||
if(zip->ppmd8_stream_failed) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated PPMd8 file body");
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated PPMd8 file body");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
@ -1985,9 +2086,10 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
|
||||
|
||||
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
||||
if(in_bytes < 1) {
|
||||
/* libbz2 doesn't complain when caller feeds avail_in == 0. It will
|
||||
* actually return success in this case, which is undesirable. This is
|
||||
* why we need to make this check manually. */
|
||||
/* libbz2 doesn't complain when caller feeds avail_in == 0.
|
||||
* It will actually return success in this case, which is
|
||||
* undesirable. This is why we need to make this check
|
||||
* manually. */
|
||||
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated bzip2 file body");
|
||||
@ -2014,16 +2116,18 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
|
||||
case BZ_OK:
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Failed to clean up bzip2 decompressor");
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Failed to clean up bzip2 "
|
||||
"decompressor");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
zip->end_of_entry = 1;
|
||||
break;
|
||||
case BZ_OK:
|
||||
/* The decompressor has successfully decoded this chunk of
|
||||
* data, but more data is still in queue. */
|
||||
/* The decompressor has successfully decoded this
|
||||
* chunk of data, but more data is still in queue. */
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
@ -2131,8 +2235,10 @@ 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 + zip->decrypted_buffer_size)
|
||||
- (zip->decrypted_ptr + zip->decrypted_bytes_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;
|
||||
@ -2143,12 +2249,12 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
|
||||
+ buff_remaining)
|
||||
> zip->entry_bytes_remaining) {
|
||||
if (zip->entry_bytes_remaining <
|
||||
(int64_t)zip->decrypted_bytes_remaining)
|
||||
(int64_t)zip->decrypted_bytes_remaining)
|
||||
buff_remaining = 0;
|
||||
else
|
||||
buff_remaining =
|
||||
(size_t)zip->entry_bytes_remaining
|
||||
- zip->decrypted_bytes_remaining;
|
||||
- zip->decrypted_bytes_remaining;
|
||||
}
|
||||
}
|
||||
if (buff_remaining > 0) {
|
||||
@ -2167,7 +2273,8 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
|
||||
+ zip->decrypted_bytes_remaining,
|
||||
&dsize);
|
||||
}
|
||||
zip->decrypted_bytes_remaining += buff_remaining;
|
||||
zip->decrypted_bytes_remaining +=
|
||||
buff_remaining;
|
||||
}
|
||||
}
|
||||
bytes_avail = zip->decrypted_bytes_remaining;
|
||||
@ -2751,7 +2858,7 @@ archive_read_format_zip_cleanup(struct archive_read *a)
|
||||
inflateEnd(&zip->stream);
|
||||
#endif
|
||||
|
||||
#if HAVA_LZMA_H && HAVE_LIBLZMA
|
||||
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
||||
if (zip->zipx_lzma_valid) {
|
||||
lzma_end(&zip->zipx_lzma_stream);
|
||||
}
|
||||
@ -3391,7 +3498,8 @@ expose_parent_dirs(struct zip *zip, const char *name, size_t name_length)
|
||||
}
|
||||
|
||||
static int
|
||||
slurp_central_directory(struct archive_read *a, struct zip *zip)
|
||||
slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
|
||||
struct zip *zip)
|
||||
{
|
||||
ssize_t i;
|
||||
unsigned found;
|
||||
@ -3501,8 +3609,10 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
|
||||
filename_length = archive_le16dec(p + 28);
|
||||
extra_length = archive_le16dec(p + 30);
|
||||
comment_length = archive_le16dec(p + 32);
|
||||
/* disk_start = archive_le16dec(p + 34); */ /* Better be zero. */
|
||||
/* internal_attributes = archive_le16dec(p + 36); */ /* text bit */
|
||||
/* disk_start = archive_le16dec(p + 34);
|
||||
* Better be zero.
|
||||
* internal_attributes = archive_le16dec(p + 36);
|
||||
* text bit */
|
||||
external_attributes = archive_le32dec(p + 38);
|
||||
zip_entry->local_header_offset =
|
||||
archive_le32dec(p + 42) + correction;
|
||||
@ -3538,7 +3648,8 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
|
||||
"Truncated ZIP file header");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
if (ARCHIVE_OK != process_extra(a, p + filename_length, extra_length, zip_entry)) {
|
||||
if (ARCHIVE_OK != process_extra(a, entry, p + filename_length,
|
||||
extra_length, zip_entry)) {
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
@ -3560,7 +3671,8 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
|
||||
* a directory. We should treat it as a non
|
||||
* resource fork file to expose it. */
|
||||
if (name[filename_length-1] != '/' &&
|
||||
(r - name < 3 || r[0] != '.' || r[1] != '_')) {
|
||||
(r - name < 3 || r[0] != '.' ||
|
||||
r[1] != '_')) {
|
||||
__archive_rb_tree_insert_node(
|
||||
&zip->tree, &zip_entry->node);
|
||||
/* Expose its parent directories. */
|
||||
@ -3637,8 +3749,10 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
||||
switch(rsrc->compression) {
|
||||
case 0: /* No compression. */
|
||||
if (rsrc->uncompressed_size != rsrc->compressed_size) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed OS X metadata entry: inconsistent size");
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed OS X metadata entry: "
|
||||
"inconsistent size");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#ifdef HAVE_ZLIB_H
|
||||
@ -3797,7 +3911,7 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a,
|
||||
a->archive.archive_format_name = "ZIP";
|
||||
|
||||
if (zip->zip_entries == NULL) {
|
||||
r = slurp_central_directory(a, zip);
|
||||
r = slurp_central_directory(a, entry, zip);
|
||||
if (r != ARCHIVE_OK)
|
||||
return r;
|
||||
/* Get first entry whose local header offset is lower than
|
||||
@ -3827,8 +3941,8 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a,
|
||||
__archive_read_reset_passphrase(a);
|
||||
|
||||
/* File entries are sorted by the header offset, we should mostly
|
||||
* use __archive_read_consume to advance a read point to avoid redundant
|
||||
* data reading. */
|
||||
* use __archive_read_consume to advance a read point to avoid
|
||||
* redundant data reading. */
|
||||
offset = archive_filter_bytes(&a->archive, 0);
|
||||
if (offset < zip->entry->local_header_offset)
|
||||
__archive_read_consume(a,
|
||||
|
@ -449,7 +449,7 @@ __archive_mktemp(const char *tmpdir)
|
||||
temp_name.s[temp_name.length-1] = '\0';
|
||||
temp_name.length --;
|
||||
}
|
||||
if (stat(temp_name.s, &st) < 0)
|
||||
if (la_stat(temp_name.s, &st) < 0)
|
||||
goto exit_tmpfile;
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
|
@ -390,10 +390,13 @@ archive_compressor_xz_options(struct archive_write_filter *f,
|
||||
data->compression_level = 6;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "threads") == 0) {
|
||||
char *endptr;
|
||||
|
||||
if (value == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
data->threads = (int)strtoul(value, NULL, 10);
|
||||
if (data->threads == 0 && errno != 0) {
|
||||
errno = 0;
|
||||
data->threads = (int)strtoul(value, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0') {
|
||||
data->threads = 1;
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
@ -2032,7 +2032,7 @@ restore_entry(struct archive_write_disk *a)
|
||||
* follow the symlink if we're creating a dir.
|
||||
*/
|
||||
if (S_ISDIR(a->mode))
|
||||
r = stat(a->name, &a->st);
|
||||
r = la_stat(a->name, &a->st);
|
||||
/*
|
||||
* If it's not a dir (or it's a broken symlink),
|
||||
* then don't follow it.
|
||||
@ -2198,7 +2198,7 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
#ifdef HAVE_LSTAT
|
||||
r = lstat(a->name, &st);
|
||||
#else
|
||||
r = stat(a->name, &st);
|
||||
r = la_stat(a->name, &st);
|
||||
#endif
|
||||
if (r != 0)
|
||||
r = errno;
|
||||
@ -2712,7 +2712,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
|
||||
* This is needed to extract hardlinks over
|
||||
* symlinks.
|
||||
*/
|
||||
r = stat(head, &st);
|
||||
r = la_stat(head, &st);
|
||||
if (r != 0) {
|
||||
tail[0] = c;
|
||||
if (errno == ENOENT) {
|
||||
@ -3052,7 +3052,7 @@ create_dir(struct archive_write_disk *a, char *path)
|
||||
* here loses the ability to extract through symlinks. Also note
|
||||
* that this should not use the a->st cache.
|
||||
*/
|
||||
if (stat(path, &st) == 0) {
|
||||
if (la_stat(path, &st) == 0) {
|
||||
if (S_ISDIR(st.st_mode))
|
||||
return (ARCHIVE_OK);
|
||||
if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
|
||||
@ -3110,7 +3110,7 @@ create_dir(struct archive_write_disk *a, char *path)
|
||||
* don't add it to the fixup list here, as it's already been
|
||||
* added.
|
||||
*/
|
||||
if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
|
||||
if (la_stat(path, &st) == 0 && S_ISDIR(st.st_mode))
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
|
||||
|
@ -1114,6 +1114,10 @@ archive_write_pax_header(struct archive_write *a,
|
||||
if (!need_extension && acl_types != 0)
|
||||
need_extension = 1;
|
||||
|
||||
/* If the symlink type is defined, we need an extension */
|
||||
if (!need_extension && archive_entry_symlink_type(entry_main) > 0)
|
||||
need_extension = 1;
|
||||
|
||||
/*
|
||||
* Libarchive used to include these in extended headers for
|
||||
* restricted pax format, but that confused people who
|
||||
@ -1247,6 +1251,17 @@ archive_write_pax_header(struct archive_write *a,
|
||||
archive_string_free(&entry_name);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Store extended symlink information */
|
||||
if (archive_entry_symlink_type(entry_main) ==
|
||||
AE_SYMLINK_TYPE_FILE) {
|
||||
add_pax_attr(&(pax->pax_header),
|
||||
"LIBARCHIVE.symlinktype", "file");
|
||||
} else if (archive_entry_symlink_type(entry_main) ==
|
||||
AE_SYMLINK_TYPE_DIRECTORY) {
|
||||
add_pax_attr(&(pax->pax_header),
|
||||
"LIBARCHIVE.symlinktype", "dir");
|
||||
}
|
||||
}
|
||||
|
||||
/* Only regular files have data. */
|
||||
|
@ -496,10 +496,13 @@ xar_options(struct archive_write *a, const char *key, const char *value)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
if (strcmp(key, "threads") == 0) {
|
||||
char *endptr;
|
||||
|
||||
if (value == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
xar->opt_threads = (int)strtoul(value, NULL, 10);
|
||||
if (xar->opt_threads == 0 && errno != 0) {
|
||||
errno = 0;
|
||||
xar->opt_threads = (int)strtoul(value, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0') {
|
||||
xar->opt_threads = 1;
|
||||
archive_set_error(&(a->archive),
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
|
@ -27,6 +27,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef HAVE_LINUX_FS_H
|
||||
#include <linux/fs.h> /* for Linux file flags */
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSCPY
|
||||
static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
@ -337,16 +341,37 @@ DEFINE_TEST(test_entry)
|
||||
/* TODO: Make this system-independent. */
|
||||
assertEqualString(archive_entry_fflags_text(e),
|
||||
"uappnd,nouchg,nodump,noopaque,uunlnk,nosystem");
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
/* Test archive_entry_copy_fflags_text_w() */
|
||||
archive_entry_copy_fflags_text_w(e, L" ,nouappnd, nouchg, dump,uunlnk");
|
||||
archive_entry_copy_fflags_text_w(e, L" ,nouappnd, nouchg, dump,hidden");
|
||||
archive_entry_fflags(e, &set, &clear);
|
||||
assertEqualInt(16, set);
|
||||
assertEqualInt(7, clear);
|
||||
assertEqualInt(UF_HIDDEN, set);
|
||||
assertEqualInt(UF_NODUMP | UF_IMMUTABLE | UF_APPEND, clear);
|
||||
/* Test archive_entry_copy_fflags_text() */
|
||||
archive_entry_copy_fflags_text(e, " ,nouappnd, nouchg, dump,uunlnk");
|
||||
archive_entry_copy_fflags_text(e, " ,nouappnd, nouchg, dump,hidden");
|
||||
archive_entry_fflags(e, &set, &clear);
|
||||
assertEqualInt(16, set);
|
||||
assertEqualInt(7, clear);
|
||||
assertEqualInt(UF_HIDDEN, set);
|
||||
assertEqualInt(UF_NODUMP | UF_IMMUTABLE | UF_APPEND, clear);
|
||||
#elif defined(_WIN32) && !defined(CYGWIN)
|
||||
archive_entry_copy_fflags_text_w(e, L"rdonly,hidden,nosystem");
|
||||
archive_entry_fflags(e, &set, &clear);
|
||||
assertEqualInt(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN, set);
|
||||
assertEqualInt(FILE_ATTRIBUTE_SYSTEM, clear);
|
||||
archive_entry_copy_fflags_text(e, "rdonly,hidden,nosystem");
|
||||
archive_entry_fflags(e, &set, &clear);
|
||||
assertEqualInt(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN, set);
|
||||
assertEqualInt(FILE_ATTRIBUTE_SYSTEM, clear);
|
||||
#elif defined FS_IOC_GETFLAGS /* Linux */
|
||||
archive_entry_copy_fflags_text_w(e, L"sappnd,schg,dump,noundel");
|
||||
archive_entry_fflags(e, &set, &clear);
|
||||
assertEqualInt(FS_APPEND_FL | FS_IMMUTABLE_FL, set);
|
||||
assertEqualInt(FS_NODUMP_FL | FS_UNRM_FL, clear);
|
||||
archive_entry_copy_fflags_text(e, "sappnd,schg,dump,noundel");
|
||||
archive_entry_fflags(e, &set, &clear);
|
||||
assertEqualInt(FS_APPEND_FL | FS_IMMUTABLE_FL, set);
|
||||
assertEqualInt(FS_NODUMP_FL | FS_UNRM_FL, clear);
|
||||
#endif
|
||||
|
||||
/* See test_acl_basic.c for tests of ACL set/get consistency. */
|
||||
|
@ -58,6 +58,14 @@ test_fuzz(const struct files *filesets)
|
||||
size_t blk_size;
|
||||
int64_t blk_offset;
|
||||
int n;
|
||||
const char *skip_fuzz_tests;
|
||||
|
||||
skip_fuzz_tests = getenv("SKIP_TEST_FUZZ");
|
||||
if (skip_fuzz_tests != NULL) {
|
||||
skipping("Skipping fuzz tests due to SKIP_TEST_FUZZ "
|
||||
"environment variable");
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; filesets[n].names != NULL; ++n) {
|
||||
const size_t buffsize = 30000000;
|
||||
|
@ -40,7 +40,30 @@ atimeIsUpdated(void)
|
||||
{
|
||||
const char *fn = "fs_noatime";
|
||||
struct stat st;
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
char *buff = NULL;
|
||||
char *ptr;
|
||||
int r;
|
||||
|
||||
r = systemf("fsutil behavior query disableLastAccess > query_atime");
|
||||
if (r == 0) {
|
||||
buff = slurpfile(NULL, "query_atime");
|
||||
if (buff != NULL) {
|
||||
ptr = buff;
|
||||
while(*ptr != '\0' && !isdigit(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr == '0') {
|
||||
free(buff);
|
||||
return(1);
|
||||
} else if (*ptr == '1' || *ptr == '2') {
|
||||
free(buff);
|
||||
return(0);
|
||||
}
|
||||
free(buff);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!assertMakeFile(fn, 0666, "a"))
|
||||
return (0);
|
||||
if (!assertUtimes(fn, 1, 0, 1, 0))
|
||||
@ -570,13 +593,13 @@ test_symlink_hybrid(void)
|
||||
assertMakeDir("h", 0755);
|
||||
assertChdir("h");
|
||||
assertMakeDir("d1", 0755);
|
||||
assertMakeSymlink("ld1", "d1");
|
||||
assertMakeSymlink("ld1", "d1", 1);
|
||||
assertMakeFile("d1/file1", 0644, "d1/file1");
|
||||
assertMakeFile("d1/file2", 0644, "d1/file2");
|
||||
assertMakeSymlink("d1/link1", "file1");
|
||||
assertMakeSymlink("d1/linkX", "fileX");
|
||||
assertMakeSymlink("link2", "d1/file2");
|
||||
assertMakeSymlink("linkY", "d1/fileY");
|
||||
assertMakeSymlink("d1/link1", "file1", 0);
|
||||
assertMakeSymlink("d1/linkX", "fileX", 0);
|
||||
assertMakeSymlink("link2", "d1/file2", 0);
|
||||
assertMakeSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
@ -727,13 +750,13 @@ test_symlink_logical(void)
|
||||
assertMakeDir("l", 0755);
|
||||
assertChdir("l");
|
||||
assertMakeDir("d1", 0755);
|
||||
assertMakeSymlink("ld1", "d1");
|
||||
assertMakeSymlink("ld1", "d1", 1);
|
||||
assertMakeFile("d1/file1", 0644, "d1/file1");
|
||||
assertMakeFile("d1/file2", 0644, "d1/file2");
|
||||
assertMakeSymlink("d1/link1", "file1");
|
||||
assertMakeSymlink("d1/linkX", "fileX");
|
||||
assertMakeSymlink("link2", "d1/file2");
|
||||
assertMakeSymlink("linkY", "d1/fileY");
|
||||
assertMakeSymlink("d1/link1", "file1", 0);
|
||||
assertMakeSymlink("d1/linkX", "fileX", 0);
|
||||
assertMakeSymlink("link2", "d1/file2", 0);
|
||||
assertMakeSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
|
||||
/* Note: this test uses archive_read_next_header()
|
||||
@ -961,8 +984,8 @@ test_symlink_logical_loop(void)
|
||||
assertMakeDir("d1/d2/d3", 0755);
|
||||
assertMakeDir("d2", 0755);
|
||||
assertMakeFile("d2/file1", 0644, "d2/file1");
|
||||
assertMakeSymlink("d1/d2/ld1", "../../d1");
|
||||
assertMakeSymlink("d1/d2/ld2", "../../d2");
|
||||
assertMakeSymlink("d1/d2/ld1", "../../d1", 1);
|
||||
assertMakeSymlink("d1/d2/ld2", "../../d2", 1);
|
||||
assertChdir("..");
|
||||
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
@ -1567,6 +1590,254 @@ test_nodump(void)
|
||||
archive_entry_free(ae);
|
||||
}
|
||||
|
||||
static void
|
||||
test_parent(void)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
const void *p;
|
||||
size_t size;
|
||||
int64_t offset;
|
||||
int file_count;
|
||||
int match_count;
|
||||
int r;
|
||||
|
||||
assertMakeDir("lock", 0311);
|
||||
assertMakeDir("lock/dir1", 0755);
|
||||
assertMakeFile("lock/dir1/f1", 0644, "0123456789");
|
||||
assertMakeDir("lock/lock2", 0311);
|
||||
assertMakeDir("lock/lock2/dir1", 0755);
|
||||
assertMakeFile("lock/lock2/dir1/f1", 0644, "0123456789");
|
||||
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
assert((a = archive_read_disk_new()) != NULL);
|
||||
|
||||
/*
|
||||
* Test1: Traverse lock/dir1 as .
|
||||
*/
|
||||
assertChdir("lock/dir1");
|
||||
|
||||
failure("Directory traversals should work as well");
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
|
||||
|
||||
file_count = 2;
|
||||
match_count = 0;
|
||||
while (file_count--) {
|
||||
archive_entry_clear(ae);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
|
||||
if (strcmp(archive_entry_pathname(ae), ".") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
|
||||
++match_count;
|
||||
} else if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
|
||||
assertEqualInt(archive_entry_size(ae), 10);
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_data_block(a, &p, &size, &offset));
|
||||
assertEqualInt((int)size, 10);
|
||||
assertEqualInt((int)offset, 0);
|
||||
assertEqualMem(p, "0123456789", 10);
|
||||
assertEqualInt(ARCHIVE_EOF,
|
||||
archive_read_data_block(a, &p, &size, &offset));
|
||||
assertEqualInt((int)size, 0);
|
||||
assertEqualInt((int)offset, 10);
|
||||
++match_count;
|
||||
}
|
||||
if (archive_read_disk_can_descend(a)) {
|
||||
/* Descend into the current object */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_disk_descend(a));
|
||||
}
|
||||
}
|
||||
failure("Did not match expected filenames");
|
||||
assertEqualInt(match_count, 2);
|
||||
/*
|
||||
* There is no entry. This will however fail if the directory traverse
|
||||
* tries to ascend past the initial directory, since it lacks permission
|
||||
* to do so.
|
||||
*/
|
||||
failure("There should be no entry and no error");
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
|
||||
|
||||
/* Close the disk object. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
|
||||
assertChdir("../..");
|
||||
|
||||
/*
|
||||
* Test2: Traverse lock/dir1 directly
|
||||
*/
|
||||
failure("Directory traversals should work as well");
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1"));
|
||||
|
||||
file_count = 2;
|
||||
match_count = 0;
|
||||
while (file_count--) {
|
||||
archive_entry_clear(ae);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
|
||||
if (strcmp(archive_entry_pathname(ae), "lock/dir1") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
|
||||
++match_count;
|
||||
} else if (strcmp(archive_entry_pathname(ae), "lock/dir1/f1") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
|
||||
assertEqualInt(archive_entry_size(ae), 10);
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_data_block(a, &p, &size, &offset));
|
||||
assertEqualInt((int)size, 10);
|
||||
assertEqualInt((int)offset, 0);
|
||||
assertEqualMem(p, "0123456789", 10);
|
||||
assertEqualInt(ARCHIVE_EOF,
|
||||
archive_read_data_block(a, &p, &size, &offset));
|
||||
assertEqualInt((int)size, 0);
|
||||
assertEqualInt((int)offset, 10);
|
||||
++match_count;
|
||||
}
|
||||
if (archive_read_disk_can_descend(a)) {
|
||||
/* Descend into the current object */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_disk_descend(a));
|
||||
}
|
||||
}
|
||||
failure("Did not match expected filenames");
|
||||
assertEqualInt(match_count, 2);
|
||||
/*
|
||||
* There is no entry. This will however fail if the directory traverse
|
||||
* tries to ascend past the initial directory, since it lacks permission
|
||||
* to do so.
|
||||
*/
|
||||
failure("There should be no entry and no error");
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
|
||||
|
||||
/* Close the disk object. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
|
||||
/*
|
||||
* Test3: Traverse lock/dir1/.
|
||||
*/
|
||||
failure("Directory traversals should work as well");
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1/."));
|
||||
|
||||
file_count = 2;
|
||||
match_count = 0;
|
||||
while (file_count--) {
|
||||
archive_entry_clear(ae);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
|
||||
if (strcmp(archive_entry_pathname(ae), "lock/dir1/.") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
|
||||
++match_count;
|
||||
} else if (strcmp(archive_entry_pathname(ae), "lock/dir1/./f1") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
|
||||
assertEqualInt(archive_entry_size(ae), 10);
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_data_block(a, &p, &size, &offset));
|
||||
assertEqualInt((int)size, 10);
|
||||
assertEqualInt((int)offset, 0);
|
||||
assertEqualMem(p, "0123456789", 10);
|
||||
assertEqualInt(ARCHIVE_EOF,
|
||||
archive_read_data_block(a, &p, &size, &offset));
|
||||
assertEqualInt((int)size, 0);
|
||||
assertEqualInt((int)offset, 10);
|
||||
++match_count;
|
||||
}
|
||||
if (archive_read_disk_can_descend(a)) {
|
||||
/* Descend into the current object */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_disk_descend(a));
|
||||
}
|
||||
}
|
||||
failure("Did not match expected filenames");
|
||||
assertEqualInt(match_count, 2);
|
||||
/*
|
||||
* There is no entry. This will however fail if the directory traverse
|
||||
* tries to ascend past the initial directory, since it lacks permission
|
||||
* to do so.
|
||||
*/
|
||||
failure("There should be no entry and no error");
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
|
||||
|
||||
/* Close the disk object. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
|
||||
/*
|
||||
* Test4: Traverse lock/lock2/dir1 from inside lock.
|
||||
*
|
||||
* This test is expected to fail on platforms with no O_EXEC or
|
||||
* equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because
|
||||
* the current traversal code can't handle the case where it can't
|
||||
* obtain an open fd for the initial current directory. We need to
|
||||
* check that condition here, because if O_EXEC _does_ exist, we don't
|
||||
* want to overlook any failure.
|
||||
*/
|
||||
assertChdir("lock");
|
||||
|
||||
failure("Directory traversals should work as well");
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1"));
|
||||
|
||||
archive_entry_clear(ae);
|
||||
r = archive_read_next_header2(a, ae);
|
||||
if (r == ARCHIVE_FAILED) {
|
||||
#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC)
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
#endif
|
||||
/* Close the disk object. */
|
||||
archive_read_close(a);
|
||||
} else {
|
||||
file_count = 2;
|
||||
match_count = 0;
|
||||
while (file_count--) {
|
||||
if (file_count == 0)
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header2(a, ae));
|
||||
if (strcmp(archive_entry_pathname(ae),
|
||||
"lock2/dir1") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae),
|
||||
AE_IFDIR);
|
||||
++match_count;
|
||||
} else if (strcmp(archive_entry_pathname(ae),
|
||||
"lock2/dir1/f1") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae),
|
||||
AE_IFREG);
|
||||
assertEqualInt(archive_entry_size(ae), 10);
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_data_block(a, &p, &size,
|
||||
&offset));
|
||||
assertEqualInt((int)size, 10);
|
||||
assertEqualInt((int)offset, 0);
|
||||
assertEqualMem(p, "0123456789", 10);
|
||||
assertEqualInt(ARCHIVE_EOF,
|
||||
archive_read_data_block(a, &p, &size,
|
||||
&offset));
|
||||
assertEqualInt((int)size, 0);
|
||||
assertEqualInt((int)offset, 10);
|
||||
++match_count;
|
||||
}
|
||||
if (archive_read_disk_can_descend(a)) {
|
||||
/* Descend into the current object */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_disk_descend(a));
|
||||
}
|
||||
}
|
||||
failure("Did not match expected filenames");
|
||||
assertEqualInt(match_count, 2);
|
||||
/*
|
||||
* There is no entry. This will however fail if the directory
|
||||
* traverse tries to ascend past the initial directory, since
|
||||
* it lacks permission to do so.
|
||||
*/
|
||||
failure("There should be no entry and no error");
|
||||
assertEqualIntA(a, ARCHIVE_EOF,
|
||||
archive_read_next_header2(a, ae));
|
||||
|
||||
/* Close the disk object. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
}
|
||||
|
||||
assertChdir("..");
|
||||
|
||||
/* Destroy the disk object. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
archive_entry_free(ae);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_disk_directory_traversals)
|
||||
{
|
||||
/* Basic test. */
|
||||
@ -1583,4 +1854,6 @@ DEFINE_TEST(test_read_disk_directory_traversals)
|
||||
test_callbacks();
|
||||
/* Test nodump. */
|
||||
test_nodump();
|
||||
/* Test parent overshoot. */
|
||||
test_parent();
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ DEFINE_TEST(test_read_extract)
|
||||
assertIsDir("dir4/b", 0755);
|
||||
assertIsDir("dir4/c", 0711);
|
||||
if (canSymlink())
|
||||
assertIsSymlink("symlink", "file");
|
||||
assertIsSymlink("symlink", "file", 0);
|
||||
|
||||
free(buff);
|
||||
free(file_buff);
|
||||
|
@ -717,4 +717,28 @@ DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file)
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
/*
|
||||
* Check mtree file with non-printable ascii characters
|
||||
*/
|
||||
DEFINE_TEST(test_read_format_mtree_noprint)
|
||||
{
|
||||
const char reffile[] = "test_read_format_mtree_noprint.mtree";
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
|
||||
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, reffile, 11));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
|
||||
assertEqualString("Can't parse line 3", archive_error_string(a));
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
begin 644 test_read_format_mtree_noprint.mtree
|
||||
K(VUT<F5E"F1I<E]O:R!T>7!E/61I<@ID:7)?P[;%H<2'('1Y<&4]9&ER"@``
|
||||
`
|
||||
end
|
@ -28,6 +28,22 @@
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
DEFINE_TEST(test_read_format_rar_set_format)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
const char reffile[] = "test_read_format_rar.rar";
|
||||
|
||||
extract_reference_file(reffile);
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_support_filter_all(a));
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_RAR));
|
||||
assertA(0 == archive_read_open_filename(a, reffile, 10240));
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_rar_basic)
|
||||
{
|
||||
char buff[64];
|
||||
@ -3740,3 +3756,26 @@ DEFINE_TEST(test_read_format_rar_multivolume_uncompressed_files)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_rar_ppmd_use_after_free)
|
||||
{
|
||||
uint8_t buf[16];
|
||||
const char* reffile = "test_read_format_rar_ppmd_use_after_free.rar";
|
||||
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_support_filter_all(a));
|
||||
assertA(0 == archive_read_support_format_all(a));
|
||||
assertA(0 == archive_read_open_filename(a, reffile, 10240));
|
||||
|
||||
assertA(ARCHIVE_OK == archive_read_next_header(a, &ae));
|
||||
assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
|
||||
assertA(ARCHIVE_OK == archive_read_next_header(a, &ae));
|
||||
assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,9 @@
|
||||
begin 644 test_read_format_rar5_distance_overflow.rar
|
||||
M4F%R(1H'`0"-[P+2``(''/\@("`@_R4``B`@("`@("`@("`@(/__("`@("`@
|
||||
M(/\@("`@("`@((9ML63,PX"&AK%:S+?_(/\@_R#_(/\@_R#_(/\@`"``!R`@
|
||||
MR<G)``#_(,G)R?___R#___\@____(/___R#___\@____R4#)R<G___\@____
|
||||
M(/\@____("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(/__________
|
||||
M____________________________________________________("`@("`@
|
||||
.("`@("`@("`@("#_("``
|
||||
`
|
||||
end
|
@ -0,0 +1,10 @@
|
||||
begin 644 test_read_format_rar5_extra_field_version.rar
|
||||
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`"BNGU4(0(#!%D&7^V#`I?:-URW@4'R
|
||||
M@`,!"&)I;B\R=&\S`P0``<7)5B550C]U!#WY13&:5TJ$=$IZ(*3`C\#F0%O\
|
||||
M)$)*@]X[RK.Z.G*HUT;V5FO&;:X/FDW,W`95I8T%@@C:DD="_8Z.9+CQH^IG
|
||||
M8!ZF0N)JSY2?R(W@25K`U&W)Q1X"`MD`!M\`[8,"E]HW7+>!0?*``P$(8FEN
|
||||
M+S)T;S/%R58E54(_=00]^44QFE=*A'1*>B"DP(_`YD!;_"1"2H/>.\JSNCIR
|
||||
MJ-=&]E9KQFVN#YI-S-P&5:6-!8((VI)'0OV.CF2X\:/J9V`>ID+B:L^4G\B-
|
||||
,X$E:P!UW5E$#!00`
|
||||
`
|
||||
end
|
@ -0,0 +1,13 @@
|
||||
begin 640 test_read_format_rar5_fileattr.rar
|
||||
M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``-$;*1"@"`PN+``2+`"&+W8Z;@```
|
||||
M#')E861O;FQY+G1X=`H#`J*C5`BE!M4!,3(S-#4V-S@@#0JYZ,#-)@(#"XL`
|
||||
M!(L`(F^$/86````*:&ED9&5N+G1X=`H#`G(Q.0^E!M4!,C,T-38W.#D@#0H>
|
||||
M%_EV)@(#"XL`!(L`)"V,TBB````*<WES=&5M+G1X=`H#`F:K01.E!M4!,S0U
|
||||
M-C<X.3`@#0HQ>$42*0(#"XL`!(L`(RZ?$!V````-<F]?:&ED9&5N+G1X=`H#
|
||||
M`JIEBD2M!M4!-C<X.3`Q,C,@#0HQAL?6)@(#"P`%`!$`````@```#&1I<E]R
|
||||
M96%D;VYL>0H#`HS,%ABE!M4!Q!O^+"0"`PL`!0`2`````(````ID:7)?:&ED
|
||||
M9&5N"@,">JRV&:4&U0'&L*8=)`(#"P`%`!0`````@```"F1I<E]S>7-T96T*
|
||||
M`P(@+D4;I0;5`2YJ1$0F`@,+``4`$P````"````,9&ER7W)O:&ED9&5N"@,"
|
||||
0CW7S@JT&U0$==U91`P4$````
|
||||
`
|
||||
end
|
@ -0,0 +1,6 @@
|
||||
begin 644 test_read_format_rar5_hardlink.rar
|
||||
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`!KI,1X'@("A0`&A0"D@P(XC;=<(1>3
|
||||
M?8```0AF:6QE+G1X=#$R,S0*[8@"T2X"`PT`!@6D@P(XC;=<`````(```0QH
|
||||
@87)D;&EN:RYT>'0,!00`"&9I;&4N='AT'7=640,%!```
|
||||
`
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
begin 644 test_read_format_rar5_invalid_dict_reference.rar
|
||||
M4F%R(1H'`0"-[P+2``+#!QR`!P`F^P#_^_O[^_O[^R4``B$<`0(`#@```0``
|
||||
M`"#2````_____QH(`/__^P#_W5)04(#_`(:&;;%DS+?,L0```````````+%D
|
||||
MS+*RLK*R/@``____Y`"R````XP```````!4``````.X`````````````````
|
||||
M%5<M;&@W;3$W"2!S;'$2C5L`_____@D0````$"('``"8F)@+````/__?````
|
||||
M@```2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$@S2(``2$A(2$A(
|
||||
>2$A(2$A(2$A(2$A(2$A(2$Q(2$A(2$A(2$A(2)](
|
||||
`
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
begin 644 test_read_format_rar5_leftshift1.rar
|
||||
M4F%R(1H'`0"-[P+2``(''(`'`"``_R4``B$<`0(`#@```0```"#2````____
|
||||
M_P`(`/__^P#_W0`"(8#_`(:&;;%DS+?,L=:NL0#(3`$`````````````````
|
||||
M``"``````````+!DS+*RL[*RL@```-P``````````````````(``````````
|
||||
ML&3,LK*RLK*R````W`````#X____````````````````````````%5H>;&@T
|
||||
M+3HW"2!SB^)_<Z3_`````?40'Q\?'Q\?'Q\?'Q\?'Q\?'Q\?'Q\?'Q\`````
|
||||
5`````````````````/H`>@``````
|
||||
`
|
||||
end
|
@ -0,0 +1,6 @@
|
||||
begin 644 test_read_format_rar5_leftshift2.rar
|
||||
M4F%R(1H'`0"-[P+2``(''(`'`2``_RL``B'+`0(`,O__````-WJ\KR<<)0`"
|
||||
M(;<*`BY*`!```&;%T#%24%"`_R4`[@K+(2Y*`&$``'__`/\E``(N2@`0`0(`
|
||||
0(?__`%N&?Q2UH.CHZ.CHZ```
|
||||
`
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
begin 644 test_read_format_rar5_nonempty_dir_stream.rar
|
||||
M4F%R(1H'`0"-[P+2``(''($'$7\`_R4``BP<`0(`(0#_Y@```"#2````____
|
||||
M_P`(`/__^P#_W0`"(8#_`(:&;;%DS+?,L8```!;(&P#>``#__^_P```4```&
|
||||
M`````````````+`!`@`A`/_F````(-(```#_____``@`___[`/_=``(A``++
|
||||
M``"`]/^`!P!#^_____\"(2$!`@`A````_R4``B$A`0(`@````0```"#&`/_=
|
||||
M``(A@/\`AH9ML63,M\R`_P```,@;`````!@`````_0`````````!87(A&@<`
|
||||
5`(WO`M(``O8'&X`'`#C[_X`E``(A
|
||||
`
|
||||
end
|
@ -0,0 +1,8 @@
|
||||
begin 644 test_read_format_rar5_owner.rar
|
||||
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`!W:E-^+0(##H4`!H4`I(,"_8VW7"$7
|
||||
MDWV```$(<F]O="YT>'0-!@,$<F]O=`5W:&5E;#$R,S0*2J"P0S,"`Q*%``:%
|
||||
M`*2#`FZ-MUQFP<VL@``!"FYO8F]D>2YT>'01!@,&;F]B;V1Y!VYO9W)O=7`U
|
||||
M-C<X"L=81/8I`@,'A0`&A0"D@P)LD[=<>B#;(H```0MN=6UE<FEC+G1X=`8&
|
||||
2#(].N$4Y.3DY"AUW5E$#!00`
|
||||
`
|
||||
end
|
@ -0,0 +1,15 @@
|
||||
begin 644 test_read_format_rar5_readtables_overflow.rar
|
||||
M4F%R(1H'`0"-[P+2`)3+'_4`C>\"T@`"T@"4RQ_5]0#O0````,L?Q_T``(`"
|
||||
MT@"4RQ_=V-C8`)3+']W=]0"-\`+2`)3+']WU`(WO`M(``M(`E,L?U?4`[P+2
|
||||
M`)3+'\?]``"``M(`E,L?W=C8V`"4RQ_=]0#V`(WO`M'UV,?8V-C8$=C8V-C8
|
||||
MV(W8V-C8V-C8V-C8V-C8V-C8V-C8V-C8V-C8!]C8V-C8V-C8V-C8V-C8V-C8
|
||||
MV-C8V-C8V-C(V-C8V-C2`)3+']W8V-C8V-C8V-C8V-C8V-C8@-C8V-C8V-C8
|
||||
MV/+8V-C8V-C8V-C8`038V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8!-C8
|
||||
MV-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8V-C8`(`"V`7V`(WO`M'U`]L?
|
||||
MW?4`C>\"T@`"T@"4'__U`(WO`N``E,L?W84`C0`0T@"4RQ_=V-C8V-C8V`"4
|
||||
MR_\R]0#V`(W8V-C8V-C8V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8V-C8
|
||||
MV-C8V-C8V-C8V-C8R-C8V-C8T@"4RQ_=V-C8V-C8V-C8V-C8V-C8V(#8V-C8
|
||||
MV-C8````9-C8V-C8V!'8V-C8V-C8]]C8V-C8V-C8V-C8V/+8V-C8V-C8V-C8
|
||||
=`038V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-@`
|
||||
`
|
||||
end
|
@ -0,0 +1,8 @@
|
||||
begin 644 test_read_format_rar5_symlink.rar
|
||||
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`"$O8RN'@("A0`&A0"D@P(XC;=<(1>3
|
||||
M?8!``0AF:6QE+G1X=#$R,S0*8QI3.2T"`PT`!@CMPP)7C;=<`````(!``0MS
|
||||
M>6UL:6YK+G1X=`P%`0`(9FEL92YT>'2.NOQU)`(#"``&`^W#`DF6MUP`````
|
||||
M@$`!!V1I<FQI;FL'!0$!`V1I<J/_?\87`@(`!P#M@P%&EK=<`````(```0-D
|
||||
*:7(==U91`P4$````
|
||||
`
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
begin 644 test_read_format_rar5_truncated_huff.rar
|
||||
M4F%R(1H'`0"-[P+2``'#]#P\7P$'`0"-[P+2``+2`!;#M#Q::7!)2?__'`!I
|
||||
M?_O_0B\*0RX-,'%O.\(#!-'^T#4````0`P1_``!#(3`P,./H`P```*^OKZ^O
|
||||
MKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ\0`*^OKZ^A``KZ``$`2^\#
|
||||
9T>WMNP$+-5H*^@`!`$OOB]$````0"S5:*@``
|
||||
`
|
||||
end
|
@ -1,68 +1,69 @@
|
||||
begin 644 test_read_format_rar5_win32.rar
|
||||
M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``/^"F5B0"`POI`@2P"2#-<,I\@`4`
|
||||
M"'1E<W0N8FEN"@,"/.U\@0U:U`'*]&4!)V5@5!]5=EV_E))QR<]EEED,<-EE
|
||||
MDQC%DA.&0DDDX9"0DDDD)..222$(220A"220DDA"$A+-M6][?3,.@'T=`ZX_
|
||||
MGKJ?]T'^]]KWW7FO.E_H`$`!`,@@GY^/;U]/+Q[^[LZ^KIZ.?EY./BX>#?W=
|
||||
MS:V=?6U=33TM#/S<S*R<C'QL7$P\&_O;R[N;BWMK6TL[*QKZZMJZJIIZ6DHZ
|
||||
M*AH)^=G)N9EY:4DTLE(R$>A0'XZ,BHF'.G#9J&A(*`?GQ[>GAV='-R<6]M:V
|
||||
MEG96-A7UU;65=54R$W]?R/T"4^B4Y_A$ET6*,&>6%VHX*:8IE!?F0M%VG48R
|
||||
MPSC`J$?_H)3&:0I?95"L5E8+BP&1:#<N!W7A!L`/,02,@GF85C0+IJ&6V#>;
|
||||
MAX.`8'(/KF$3H*9V&`\#;>A[O8=7T(W\6$"-&#'G"AY-"8-B^.#F.APB!*GA
|
||||
MA18[8T/Y\5"`;"$-"(32,9R0+R4`8B?AZB4"`POG`@2`("#&LA-^@`4`"71E
|
||||
M<W0Q+F)I;@H#`A*5H8`-6M0!R/!C`1!D168O5P5_4DDDDDDDDDDDDDDDDDDD
|
||||
MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD^_/D;F=O/:[?;Z2Z_N
|
||||
M[6[OF=&;N]._TF,S#.GS#C<WS/.'/XKG;\@`@`@!L,/'3AM\>_MZ^GGY>/AW
|
||||
M]W;V=?5T]'/S<O)Q\7#P;^]N[FWM;.QKZVKJ:>EHZ&?G9N9EY63D8^-BXF'A
|
||||
M8.!?WU[>7=U<W%O;6MI9V5C85]=6UE755-13TU+24=%0T$_/3LY-S4S,2\M*
|
||||
MRDG)2,A'QT;&1<5$Q$/#0L)!P4#`/[\^^]['VA2X4M7TE0H#.Q@!;-"-XC0$
|
||||
M.A"U@6`X1/;M+3@AZ=F@%F`%LT(W2-`0Z$+6!8#A$]N4M."'IR:`68`6S0C<
|
||||
M(T!#H0M8%@.$3VW2TX(>FYH!9@!;-"-LC0$.A"U@6`X1-8__0K^QS*_>TU/6
|
||||
MRJ_(8IKGE-.XIH6GK_HGV@`)6BG`)0(#"^8"!(`@(,NO9O&`!0`)=&5S=#(N
|
||||
M8FEN"@,"A/;"@`U:U`'/]F(!$&1%9B]7!7]2222222222222222222222222
|
||||
M2222222222222222222222222222222222223[\^1N9V\]KM]OI+K^[M;N^9
|
||||
MT9N[T[_28S,,Z?,.-S?,\X<_BN=OR`"`"`&IAXZ<-OCW]O7T\_+Q\._N[>SK
|
||||
MZNGHY^;EY./BX>#?WMW<V]K9V-?6U=33TM'0S\[-S,O*R<C'QL7$P\+!P+^^
|
||||
MO;R[NKFXM[:UM+.RL;"OKJVLJZJIJ*>FI:2CHJ&@GYZ=G)N:F9B7EI64DY*1
|
||||
MD(^.C8R+BHF(AX:%A(."@8!_?GWWO8^T*7"EJ^DJ%`9V,`+9H1O$:`AT(6L"
|
||||
MP'")[=I:<$/3LT`LP`MFA&Z1H"'0A:P+`<(GMREIP0].30"S`"V:$;A&@(="
|
||||
M%K`L!PB>VZ6G!#TW-`+,`+9H1MD:`AT(6L"P'")K'_Z%?V.97[VFIZV57Y#%
|
||||
M-<\IIW%-"T]?]$^TVMWAVR4"`POT`@2`("#9([&?@`4`"71E<W0S+F)I;@H#
|
||||
M`H1PWX`-6M0!RN%P`1!D554O5P5^))))))))))))))))))))))))))))))))
|
||||
M))))))))))))))))))))))))))))))SO.\[S<:UGCPYS=>O+LEY]]M9^&\\,
|
||||
MWO7CO^DQF89X_9MAKF??:-?Q7/7Y`!`!`#848765^/?V]?3S\O'P[^[M[.OJ
|
||||
MZ>CGYN7DX^+AX-_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'`O[Z]
|
||||
MO+NZN;BWMK6TL[*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV<FYJ9F)>6E923DI&0
|
||||
MCXZ-C(N*B8B'AH6$@X*!@']^??=]3[8AOPALOH4&#J;"`FDX$V"95@TP3;@P
|
||||
MF6DRPI=O")0\&G@!T,0$TG`FN3*KFER;<&$RTF6%+MV1*'@T[`.AB`FDX$UB
|
||||
M958T/&FX`#:3+"EVZ(E#P:=`'0Q`32<":I,JJ:'C3<`!M)EA2^4__8C^QK(_
|
||||
M>\:'K=J/R*(<ZY#CV(<&IZ_]"_:`$R,0$"4"`POT`@2`("#4/L00@`4`"71E
|
||||
M<W0T+F)I;@H#`@*,&8$-6M0!R^!P`1!D554O5P5^I)))))))))))))))))))
|
||||
M))))))))))))))))))))))))))))))))))))))))))SO.\YS<:UGCPYS=>O+
|
||||
MLEY]]M9^&\\,WO7CO^DQF89X_9MAKF??:-?Q7/7Y`!`!`#7=,+*J?'O[>OIY
|
||||
M^7CX=_=V]G7U=/1S\W+R<?%P\&_O;NYM[6SL:^MJZFGI:.AGYV;F9>5DY&/C
|
||||
M8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!/ST[.3<U,
|
||||
MS$O+2LI)R4C(1\=&QD7%1,1#PT+"0<%`P#^_/ON^Z^V(;\(;+Z%!@ZFP@)I.
|
||||
M!-@F58-,$VX,)EI,L*7:Y$H>#2X!T,0$TG`FL3*K&EB;<&$RTF6%+MX1*'@T
|
||||
M\`.AB`FDX$U2954T/&FX`#:3+"EV[(E#P:=@'0Q`32<":A,JH:'C3<`!M)EA
|
||||
M2^=?_L1_8UD?O>-#UNU'Y%$.=<AQ[$.#4]?^A?M`Y!DD9R4"`PO\`@2`("#R
|
||||
M5=&Y@`4`"71E<W0U+F)I;@H#`BI\2($-6M0!S.]X`1!D554O=6ZDDDDDDDDD
|
||||
MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDG.\[SO-Q
|
||||
MFM>/..;N7KV[)>??;>LS[/'-[UX[_28S,,\?L,TUS/OM&_Q7/7Y`!`!`#6<+
|
||||
MK*J?'O[>OIY^7CX=_=V]G7U=/1S\W+R<?%P\&_O;NYM[6SL:^MJZFGI:.AGY
|
||||
MV;F9>5DY&/C8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14
|
||||
M-!/ST[.3<U,S$O+2LI)R4C(1\=&QD7%1,1#PT+"0<%`P#^_/ON^X^W$)PA)M
|
||||
MD@@5^H.&2UDI2.+AC"BYI<-/"!MIL`Z/;L$0M;)V8*FSADM9*4CBP8PHL:6#
|
||||
M3P@;:;`.CVZ!$+6R=&"ILX9+62E(XJ&,**FE0T\(&VFP#H]N01"ULG)@J;.&
|
||||
M2UDI2.*!C"BAI0-/"!MIL`Z/G'_[B/[&LC][QH>MVH_(HAYUR'CV(>#4]?^@
|
||||
M_:`_"MBZ)0(#"_P"!(`@(/](I#:`!0`)=&5S=#8N8FEN"@,"%79G@0U:U`'-
|
||||
M[G@!$&1552]U;J2222222222222222222222222222222222222222222222
|
||||
M222222222222222<[SO.\W&:UX\XYNY>O;LEY]]MZS/L\<WO7CO])C,PSQ^P
|
||||
MS37,^^T;_%<]?D`$`$`-TX7654^/?V]?3S\O'P[^[M[.OJZ>CGYN7DX^+AX-
|
||||
M_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'`O[Z]O+NZN;BWMK6TL[
|
||||
M*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV<FYJ9F)>6E923DI&0CXZ-C(N*B8B'AH
|
||||
M6$@X*!@']^??=]Q]N(3A"3;)!`K]0<,EK)2D<7#&%%S2X:>$#;38!T>W8(A:
|
||||
MV3LP5-G#):R4I'%@QA18TL&GA`VTV`='MT"(6MDZ,%39PR6LE*1Q4,845-*A
|
||||
MIX0-M-@'1[<@B%K9.3!4V<,EK)2D<4#&%%#2@:>$#;38!T?./_W$?V-9'[WC
|
||||
;0];M1^11#SKD/'L0\&IZ_]!^T!UW5E$#!00`
|
||||
M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``EV&"+"$"`PL`!0`0`````(````=T
|
||||
M97-T9&ER"@,"5N<QTHH!U0&_NE<D)`(#"^D"!+`)(,UPRGR``P`(=&5S="YB
|
||||
M:6X*`P(\[7R!#5K4`<KT90$G96!4'U5V7;^4DG')SV6660QPV663&,62$X9"
|
||||
M223AD)"2220DXY))(0A))"$)))"22$(2$LVU;WM],PZ`?1T#KC^>NI_W0?[W
|
||||
MVO?=>:\Z7^@`0`$`R""?GX]O7T\O'O[NSKZNGHY^7DX^+AX-_=W-K9U];5U-
|
||||
M/2T,_-S,K)R,?&Q<3#P;^]O+NYN+>VM;2SLK&OKJVKJJFGI:2CHJ&@GYV<FY
|
||||
MF7EI232R4C(1Z%`?CHR*B8<Z<-FH:$@H!^?'MZ>'9T<W)Q;VUK:6=E8V%?75
|
||||
MM95U53(3?U_(_0)3Z)3G^$2718HP9Y87:C@IIBF4%^9"T7:=1C+#.,"H1_^@
|
||||
ME,9I"E]E4*Q65@N+`9%H-RX'=>$&P`\Q!(R">9A6-`NFH9;8-YN'@X!@<@^N
|
||||
M81.@IG88#P-MZ'N]AU?0C?Q80(T8,><*'DT)@V+XX.8Z'"($J>&%%CMC0_GQ
|
||||
M4(!L(0T(A-(QG)`O)0`QGD%J)0(#"^L"!(`@(,:R$WZ``P`)=&5S=#$N8FEN
|
||||
M"@,"$I6A@`U:U`'-\6<!$&1&92]7!7^22222222222222222222222222222
|
||||
M222222222222222222222222222222223GY^RW,[??J[><7#G7SNUN[YG1F[
|
||||
MO3O]%F,,Z?#,/6YOF>>GO;]_`_=OV`"`"`&PPZ<-FGU\_'O[>OIY^7CX=_=V
|
||||
M]G7U=/1S\W+R<?%P\&_O;NYM[6SL:^MJZFGI:.AGYV;F9>5DY&/C8N)AX6#@
|
||||
M7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!/ST[.3<U,S$O+2LI)
|
||||
MR4C(1\=&QD7%1,1#PT+"0<%`P#_[WL?R%+A2U?J5"@,[&`%LT(W2-`0Z$+6!
|
||||
M8#A$]N4M."'IR:`68`6S0C<(T!#H0M8%@.$3VW2TX(>FYH!9@!;-"-LC0$.A
|
||||
M"U@6`X1/;5+3@AZ:F@%F`%LT(VB-`0Z$+6!8#A$UA]Z%,?GS*>SVE?X8*>=C
|
||||
M4\-BG=.J=HXIZ?]R?M!(:PP')0(#"^L"!(`@(<NO9O&``P`)=&5S=#(N8FEN
|
||||
M"@,"A/;"@`U:U`',\&<!$&1&92]7!7^22222222222222222222222222222
|
||||
M222222222222222222222222222222223GY^RW,[??J[><7#G7SNUN[YG1F[
|
||||
MO3O]%F,,Z?#,/6YOF>>GO;]_`_=OV`"`"`&IATX;-/KY^/?V]?3S\O'P[^[M
|
||||
M[.OJZ>CGYN7DX^+AX-_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'`
|
||||
MO[Z]O+NZN;BWMK6TL[*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV<FYJ9F)>6E923
|
||||
MDI&0CXZ-C(N*B8B'AH6$@X*!@'_WO8_D*7"EJ_4J%`9V,`+9H1ND:`AT(6L"
|
||||
MP'")[<I:<$/3DT`LP`MFA&X1H"'0A:P+`<(GMNEIP0]-S0"S`"V:$;9&@(="
|
||||
M%K`L!PB>VJ6G!#TU-`+,`+9H1M$:`AT(6L"P'")K#[T*8_/F4]GM*_PP4\[&
|
||||
MIX;%.Z=4[1Q3T_[D_:#Z7*U;)0(#"_<"!(`@(-DCL9^``P`)=&5S=#,N8FEN
|
||||
M"@,"A'#?@`U:U`'.YG,!$&1552]7!7XDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
|
||||
MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDG>\[SO-RUK/'AS>Z]>]72\[VUGX;
|
||||
MSPS6]^._Z+,89X_&9MAOF??:->O/X'?K\@`@`@!LK,L+N/CW]O7T\_+Q\._N
|
||||
M[>SKZNGHY^;EY./BX>#?WMW<V]K9V-?6U=33TM'0S\[-S,O*R<C'QL7$P\+!
|
||||
MP+^^O;R[NKFXM[:UM+.RL;"OKJVLJZJIJ*>FI:2CHJ&@GYZ=G)N:F9B7EI64
|
||||
MDY*1D(^.C8R+BHF(AX:%A(."@8!_?O_[[UOQB$^$)+[%!@ZJP@)I6!-DF59-
|
||||
M,DTP85+::84MW9$H?1AV`=#$!-*P)L$RK!I@FF#"I;33"ENZ(E#Z,.@#H8@)
|
||||
MI6!-<F57-#AI,`!MIIA2W<D2A]&'(!T,0$TK`FX)E7!H<-)@`-M-,*7RW][$
|
||||
M+?7[(?3[2/T-$/>UH>G1#RK4/$L0^/_<7F@SHER0)0(#"_<"!(`@(-0^Q!"`
|
||||
M`P`)=&5S=#0N8FEN"@,"`HP9@0U:U`'/YW,!$&1552]7!7XDDDDDDDDDDDDD
|
||||
MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDG.\[SG-RUK/'
|
||||
MASFZ]>]72\[VUGX;SPS6]^._Z+,89X_&9MAOF??:->O/X'?K\@`@`@!L*,KK
|
||||
M*_'O[>OIY^7CX=_=V]G7U=/1S\W+R<?%P\&_O;NYM[6SL:^MJZFGI:.AGYV;
|
||||
MF9>5DY&/C8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!
|
||||
M/ST[.3<U,S$O+2LI)R4C(1\=&QD7%1,1#PT+"0<%`P#^_?_WWJ?C$.>$.%]B
|
||||
M@P=380$TG`FR3*LFF2;D&$RVFF%+=@B4/HPP`=#$!-)P)KDRJYI<FY!A,MII
|
||||
MA2W=D2A]&'8!T,0$TG`FL3*K&APTY``;::84MW1$H?1AT`=#$!-)P)JDRJIH
|
||||
M<-.0`&VFF%+Y3^]B%/K]D/I]I'Z&B'O:T/3HAY5J'B6(?'_N+S0M?'0I)0(#
|
||||
M"X`#!(`@(/)5T;F``P`)=&5S=#4N8FEN"@,"*GQ(@0U:U`'([WP!$&1552]U
|
||||
M;J2222222222222222222222222222222222222222222222222222222222
|
||||
M222<[SO.\W+-:\><<W<O7O5TO.]MYF?9XZUO?CO]%F,,\?C,,TUW/OM&_7OX
|
||||
M'GK\@`@`@!K.%UE5/CW]O7T\_+Q\._N[>SKZNGHY^;EY./BX>#?WMW<V]K9V
|
||||
M-?6U=33TM'0S\[-S,O*R<C'QL7$P\+!P+^^O;R[NKFXM[:UM+.RL;"OKJVLJ
|
||||
MZJIJ*>FI:2CHJ&@GYZ=G)N:F9B7EI64DY*1D(^.C8R+BHF(AX:%A(."@8!_?
|
||||
MO_[[W'XXA.D)1LT$"OW!PR6LE*QQ<,847-+AIH@;:C`.CV[!$+6S=F"ILX9+
|
||||
M62E8XL&,*+&E@TT0-M1@'1[=`B%K9NC!4V<,EK)2L<5#&%%32H::(&VHP#H]
|
||||
MN01"ULW)@J;.&2UDI6.*!C"BAI0--$#;48!T?G'][B''U_9#Z?:1^AHA[VM#
|
||||
MT\$/*RH>)D0^/_</F@#V;XCT)0(#"X`#!(`@(/](I#:``P`)=&5S=#8N8FEN
|
||||
M"@,"%79G@0U:U`')[GP!$&1552]U;J222222222222222222222222222222
|
||||
M2222222222222222222222222222222<[SO.\W+-:\><<W<O7O5TO.]MYF?9
|
||||
MXZUO?CO]%F,,\?C,,TUW/OM&_7OX'GK\@`@`@!NG"ZRJGQ[^WKZ>?EX^'?W=
|
||||
MO9U]73T<_-R\G'Q</!O[V[N;>UL[&OK:NIIZ6CH9^=FYF7E9.1CXV+B8>%@X
|
||||
M%_?7MY=W5S<6]M:VEG96-A7UU;65=54U%/34M)1T5#03\].SDW-3,Q+RTK*2
|
||||
M<E(R$?'1L9%Q43$0\-"PD'!0,`_OW_]][C\<0G2$HV:"!7[@X9+62E8XN&,*
|
||||
M+FEPTT0-M1@'1[=@B%K9NS!4V<,EK)2L<6#&%%C2P::(&VHP#H]N@1"ULW1@
|
||||
MJ;.&2UDI6.*AC"BII4--$#;48!T>W((A:V;DP5-G#):R4K'%`QA10TH&FB!M
|
||||
KJ,`Z/SC^]Q#CZ_LA]/M(_0T0][6AZ>"'E94/$R(?'_N'S0`==U91`P4$````
|
||||
`
|
||||
end
|
||||
|
@ -0,0 +1,10 @@
|
||||
begin 644 test_read_format_rar_ppmd_use_after_free.rar
|
||||
M4F%R(1H'``1G=$Q26`!W````>U!+`P0R`'#_J7\`+@TU'`#]`0`7__]"0D)"
|
||||
M+W5N<V5T"6=I9`UD#1T+``!"`````````&%R(1H'``1G>TQ26`!W=&@`[E!+
|
||||
M`P0Q`'#_(````"`@(+<@!/T`("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
||||
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(`1G=$Q26`!W````
|
||||
M>U!+`P0R`'#_J7\`+@TU'`#]`0`7__]"0D)"+W5N<V5T"6=I9`UD#1T+``!"
|
||||
@`````````&%R(1H'``1G>TQ26`!W=&@`[E!+`P0Q`'``
|
||||
`
|
||||
end
|
@ -36,6 +36,7 @@ DEFINE_TEST(test_read_format_raw)
|
||||
const char *reffile1 = "test_read_format_raw.data";
|
||||
const char *reffile2 = "test_read_format_raw.data.Z";
|
||||
const char *reffile3 = "test_read_format_raw.bufr";
|
||||
const char *reffile4 = "test_read_format_raw.data.gz";
|
||||
|
||||
/* First, try pulling data out of an uninterpretable file. */
|
||||
extract_reference_file(reffile1);
|
||||
@ -117,4 +118,30 @@ DEFINE_TEST(test_read_format_raw)
|
||||
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));
|
||||
|
||||
/* Fourth, try with gzip which has metadata. */
|
||||
extract_reference_file(reffile4);
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_filename(a, reffile4, 1));
|
||||
|
||||
/* First (and only!) Entry */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("test-file-name.data", archive_entry_pathname(ae));
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
|
||||
assert(archive_entry_mtime_is_set(ae));
|
||||
assertEqualIntA(a, archive_entry_mtime(ae), 0x5cbafd25);
|
||||
/* Most fields should be unset (unknown) */
|
||||
assert(!archive_entry_size_is_set(ae));
|
||||
assert(!archive_entry_atime_is_set(ae));
|
||||
assert(!archive_entry_ctime_is_set(ae));
|
||||
|
||||
/* Test EOF */
|
||||
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));
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
begin 644 test_read_format_raw.data.gz
|
||||
L'XL(""7]NEP``W1E<W0M9FEL92UN86UE+F1A=&$`2\O/YP(`J&4R?@0`````
|
||||
`
|
||||
end
|
@ -0,0 +1,53 @@
|
||||
/*-
|
||||
* Copyright (c) 2019 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"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Tar archives with with just a GNU label (or ending with one) should
|
||||
* be treated as valid (empty) archives
|
||||
*/
|
||||
DEFINE_TEST(test_read_format_tar_empty_with_gnulabel)
|
||||
{
|
||||
char name[] = "test_read_format_tar_empty_with_gnulabel.tar";
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
|
||||
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));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
|
||||
|
||||
/* Read first entry. */
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
|
||||
/* Verify that the format detection worked. */
|
||||
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
|
||||
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
begin 664 test_read_format_tar_empty_with_gnulabel.tar
|
||||
M;&%B96P`````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`#$S-#8W-S,V,C`S`#`P,C8R,``@5@``````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
9````````````````````````````````````
|
||||
`
|
||||
end
|
@ -32,29 +32,29 @@ __FBSDID("$FreeBSD$");
|
||||
static
|
||||
int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc)
|
||||
{
|
||||
la_ssize_t fsize, bytes_read;
|
||||
uint8_t* buf;
|
||||
int ret = 1;
|
||||
uint32_t computed_crc;
|
||||
la_ssize_t fsize, bytes_read;
|
||||
uint8_t* buf;
|
||||
int ret = 1;
|
||||
uint32_t computed_crc;
|
||||
|
||||
fsize = (la_ssize_t) archive_entry_size(ae);
|
||||
buf = malloc(fsize);
|
||||
if(buf == NULL)
|
||||
return 1;
|
||||
fsize = (la_ssize_t) archive_entry_size(ae);
|
||||
buf = malloc(fsize);
|
||||
if(buf == NULL)
|
||||
return 1;
|
||||
|
||||
bytes_read = archive_read_data(a, buf, fsize);
|
||||
if(bytes_read != fsize) {
|
||||
assertEqualInt(bytes_read, fsize);
|
||||
goto fn_exit;
|
||||
}
|
||||
bytes_read = archive_read_data(a, buf, fsize);
|
||||
if(bytes_read != fsize) {
|
||||
assertEqualInt(bytes_read, fsize);
|
||||
goto fn_exit;
|
||||
}
|
||||
|
||||
computed_crc = crc32(0, buf, fsize);
|
||||
assertEqualInt(computed_crc, crc);
|
||||
ret = 0;
|
||||
computed_crc = crc32(0, buf, fsize);
|
||||
assertEqualInt(computed_crc, crc);
|
||||
ret = 0;
|
||||
|
||||
fn_exit:
|
||||
free(buf);
|
||||
return ret;
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -111,7 +111,7 @@ verify_basic(struct archive *a, int seek_checks)
|
||||
int64_t o;
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("ZIP 1.0 (uncompressed)", archive_format_name(a));
|
||||
assertEqualString("ZIP 1.0 (uncompressed)", archive_format_name(a));
|
||||
assertEqualString("dir/", archive_entry_pathname(ae));
|
||||
assertEqualInt(1179604249, archive_entry_mtime(ae));
|
||||
assertEqualInt(0, archive_entry_size(ae));
|
||||
@ -124,7 +124,7 @@ verify_basic(struct archive *a, int seek_checks)
|
||||
assertEqualInt((int)s, 0);
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
assertEqualString("file1", archive_entry_pathname(ae));
|
||||
assertEqualInt(1179604289, archive_entry_mtime(ae));
|
||||
if (seek_checks)
|
||||
@ -144,7 +144,7 @@ verify_basic(struct archive *a, int seek_checks)
|
||||
}
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
assertEqualString("file2", archive_entry_pathname(ae));
|
||||
assertEqualInt(1179605932, archive_entry_mtime(ae));
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
@ -166,7 +166,7 @@ verify_basic(struct archive *a, int seek_checks)
|
||||
assert(archive_errno(a) != 0);
|
||||
}
|
||||
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a));
|
||||
/* Verify the number of files read. */
|
||||
failure("the archive file has three files");
|
||||
assertEqualInt(3, archive_file_count(a));
|
||||
@ -493,9 +493,14 @@ DEFINE_TEST(test_read_format_zip_lzma_one_file)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping("lzma reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
@ -513,9 +518,14 @@ DEFINE_TEST(test_read_format_zip_lzma_one_file_blockread)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping("lzma reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
@ -533,9 +543,14 @@ DEFINE_TEST(test_read_format_zip_lzma_multi)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping("lzma reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
|
||||
@ -565,9 +580,14 @@ DEFINE_TEST(test_read_format_zip_lzma_multi_blockread)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping("lzma reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
|
||||
@ -598,9 +618,14 @@ DEFINE_TEST(test_read_format_zip_bzip2_one_file)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
|
||||
skipping("bzip2 is not fully supported on this platform");
|
||||
archive_read_close(a);
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
@ -618,9 +643,14 @@ DEFINE_TEST(test_read_format_zip_bzip2_one_file_blockread)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
|
||||
skipping("bzip2 is not fully supported on this platform");
|
||||
archive_read_close(a);
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
@ -638,9 +668,14 @@ DEFINE_TEST(test_read_format_zip_bzip2_multi)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
|
||||
skipping("bzip2 is not fully supported on this platform");
|
||||
archive_read_close(a);
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
|
||||
@ -670,9 +705,14 @@ DEFINE_TEST(test_read_format_zip_bzip2_multi_blockread)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
|
||||
skipping("bzip2 is not fully supported on this platform");
|
||||
archive_read_close(a);
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
|
||||
@ -702,9 +742,14 @@ DEFINE_TEST(test_read_format_zip_xz_multi)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping("lzma reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
|
||||
@ -734,9 +779,14 @@ DEFINE_TEST(test_read_format_zip_xz_multi_blockread)
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping("lzma reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
|
||||
@ -789,9 +839,14 @@ DEFINE_TEST(test_read_format_zip_bz2_hang_on_invalid)
|
||||
struct archive_entry *ae;
|
||||
char buf[8];
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
|
||||
skipping("bzip2 is not fully supported on this platform");
|
||||
archive_read_close(a);
|
||||
return;
|
||||
}
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
@ -823,3 +878,41 @@ DEFINE_TEST(test_read_format_zip_ppmd8_crash_2)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_lzma_alone_leak)
|
||||
{
|
||||
const char *refname = "test_read_format_zip_lzma_alone_leak.zipx";
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
char buf[64];
|
||||
|
||||
/* OSSFuzz #14470 sample file. */
|
||||
extract_reference_file(refname);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
if(ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
|
||||
skipping("lzma reading is not fully supported on this platform");
|
||||
archive_read_close(a);
|
||||
return;
|
||||
}
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
|
||||
/* Extraction of this file should fail, because the sample file is invalid.
|
||||
* But it shouldn't crash. */
|
||||
assertEqualIntA(a, ARCHIVE_FAILED, archive_read_data(a, buf, sizeof(buf)));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
|
||||
/* Extraction of this file should fail, because the sample file is invalid.
|
||||
* But it shouldn't crash. */
|
||||
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, sizeof(buf)));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
/* This testcase shouldn't produce any memory leaks. When running test
|
||||
* suite under Valgrind or ASan, the test runner won't return with
|
||||
* exit code 0 in case if a memory leak. */
|
||||
}
|
||||
|
@ -0,0 +1,102 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2019 Mike Frysinger
|
||||
* 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$");
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
static void
|
||||
verify(struct archive *a) {
|
||||
struct archive_entry *ae;
|
||||
const char *p;
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assert((p = archive_entry_pathname_utf8(ae)) != NULL);
|
||||
assertEqualUTF8String(p, "File 1.txt");
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assert((p = archive_entry_pathname_utf8(ae)) != NULL);
|
||||
#if defined(__APPLE__)
|
||||
/* Compare NFD string. */
|
||||
assertEqualUTF8String(p, "File 2 - o\xCC\x88.txt");
|
||||
#else
|
||||
/* Compare NFC string. */
|
||||
assertEqualUTF8String(p, "File 2 - \xC3\xB6.txt");
|
||||
#endif
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assert((p = archive_entry_pathname_utf8(ae)) != NULL);
|
||||
#if defined(__APPLE__)
|
||||
/* Compare NFD string. */
|
||||
assertEqualUTF8String(p, "File 3 - a\xCC\x88.txt");
|
||||
#else
|
||||
/* Compare NFC string. */
|
||||
assertEqualUTF8String(p, "File 3 - \xC3\xA4.txt");
|
||||
#endif
|
||||
|
||||
/* The CRC of the filename fails, so fall back to CDE. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assert((p = archive_entry_pathname_utf8(ae)) != NULL);
|
||||
assertEqualUTF8String(p, "File 4 - xx.txt");
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_utf8_paths)
|
||||
{
|
||||
const char *refname = "test_read_format_zip_7075_utf8_paths.zip";
|
||||
struct archive *a;
|
||||
char *p;
|
||||
size_t s;
|
||||
|
||||
extract_reference_file(refname);
|
||||
|
||||
if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
|
||||
skipping("en_US.UTF-8 locale not available on this system.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify with seeking reader. */
|
||||
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, 10240));
|
||||
verify(a);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
/* Verify with streaming reader. */
|
||||
p = slurpfile(&s, refname);
|
||||
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, read_open_memory(a, p, s, 31));
|
||||
verify(a);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_free(a));
|
||||
free(p);
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
begin 644 test_read_format_zip_7075_utf8_paths.zip
|
||||
M4$L#!!0````(`,$^9D5BZ95P"P````D````*````1FEL92`Q+G1X=`M)+2Y1
|
||||
M2,O,204`4$L#!!0````(`,$^9D5BZ95P"P````D````/`!@`1FEL92`R("T@
|
||||
M>'@N='AT=7`4``$NSPQQ1FEL92`R("T@P[8N='AT"TDM+E%(R\Q)!0!02P,$
|
||||
M%`````@`P3YF16+IE7`+````"0````\`&`!&:6QE(#,@+2!X>"YT>'1U<!0`
|
||||
M`1"DSIY&:6QE(#,@+2##I"YT>'0+22TN44C+S$D%`%!+`P04````"`#!/F9%
|
||||
M8NF5<`L````)````#P`8`$9I;&4@-"`M('AX+G1X='5P%``!G[AP'$9I;&4@
|
||||
M-"`M(,.E+G1X=`M)+2Y12,O,204`4$L!`A\`%`````@`P3YF16+IE7`+````
|
||||
M"0````H`)``````````@`````````$9I;&4@,2YT>'0*`"````````$`&``Q
|
||||
M6UASCOG/`5^OQVV.^<\!7Z_';8[YSP%02P$"'P`4````"`#!/F9%8NF5<`L`
|
||||
M```)````#@`\`````````"`````S````1FEL92`R("T@E"YT>'0*`"``````
|
||||
M``$`&``Q6UASCOG/`2M.B72.^<\!*TZ)=([YSP%U<!0``2[/#'%&:6QE(#(@
|
||||
M+2##MBYT>'102P$"'P`4````"`#!/F9%8NF5<`L````)````#@`\````````
|
||||
M`"````"#````1FEL92`S("T@A"YT>'0*`"````````$`&``Q6UASCOG/`5<$
|
||||
M&W>.^<\!5P0;=X[YSP%U<!0``1"DSIY&:6QE(#,@+2##I"YT>'102P$"'P`4
|
||||
M````"`#!/F9%8NF5<`L````)````#@`\`````````"````#3````1FEL92`T
|
||||
M("T@ABYT>'0*`"````````$`&``Q6UASCOG/`6#)ZG:.^<\!8,GJ=H[YSP%U
|
||||
M<!0``9^X<!Q&:6QE(#0@+2##I2YT>'102P4&``````0`!`#$`0``(P$`````
|
||||
`
|
||||
end
|
@ -0,0 +1,93 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2018 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"
|
||||
|
||||
/*
|
||||
* Test archive verifies that we ignore padding in the extra field.
|
||||
*
|
||||
* APPNOTE.txt does not provide any provision for padding the extra
|
||||
* field, so libarchive used to error when there were unconsumed
|
||||
* bytes. Apparently, some Zip writers do routinely put zero padding
|
||||
* in the extra field.
|
||||
*
|
||||
* The extra fields in this test (for both the local file header
|
||||
* and the central directory entry) are formatted as follows:
|
||||
*
|
||||
* 0000 0000 - unrecognized field with type zero, zero bytes
|
||||
* 5554 0900 03d258155cdb58155c - UX field with length 9
|
||||
* 0000 0400 00000000 - unrecognized field with type zero, four bytes
|
||||
* 000000 - three bytes padding
|
||||
*
|
||||
* The two valid type zero fields should be skipped and ignored, as
|
||||
* should the three bytes padding (which is too short to be a valid
|
||||
* extra data object). If there were no errors and we read the UX
|
||||
* field correctly, then we've correctly handled all of the padding
|
||||
* fields above.
|
||||
*/
|
||||
|
||||
|
||||
static void verify(struct archive *a) {
|
||||
struct archive_entry *ae;
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualString("a", archive_entry_pathname(ae));
|
||||
assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae));
|
||||
assertEqualInt(0x5c1558d2, archive_entry_mtime(ae));
|
||||
assertEqualInt(0, archive_entry_ctime(ae));
|
||||
assertEqualInt(0x5c1558db, archive_entry_atime(ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_extra_padding)
|
||||
{
|
||||
const char *refname = "test_read_format_zip_extra_padding.zip";
|
||||
struct archive *a;
|
||||
char *p;
|
||||
size_t s;
|
||||
|
||||
extract_reference_file(refname);
|
||||
|
||||
/* Verify with seeking reader. */
|
||||
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, 7));
|
||||
verify(a);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
/* Verify with streaming reader. */
|
||||
p = slurpfile(&s, refname);
|
||||
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, read_open_memory(a, p, s, 3));
|
||||
verify(a);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
begin 644 test_read_format_zip_extra_padding.zip
|
||||
M4$L#!`H``````"-=CTW$\L?V`@````(````!`!P`80````!55`D``])8%5S;
|
||||
M6!5<```$``````````!B"E!+`0(>`PH``````"-=CTW$\L?V`@````(````!
|
||||
M`!@```````$```"D@0````!A`````%54"0`#TE@57-M8%5P```0``````$L%
|
||||
3!@`````!``$`1P```#T`````````
|
||||
`
|
||||
end
|
@ -0,0 +1,5 @@
|
||||
begin 644 test_read_format_zip_lzma_alone_leak.zipx
|
||||
M4$L#!"`@6B`.("`@("`@("`@%0```"`@("````4``0`!`"`@(`4``"``````
|
||||
J(/\@("`@("`@("!02P,$("`@(`X@(/________\@("`@("`@(``````@
|
||||
`
|
||||
end
|
@ -68,6 +68,14 @@ struct sparse {
|
||||
|
||||
static void create_sparse_file(const char *, const struct sparse *);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* On APFS holes need to be at least 4096x4097 bytes */
|
||||
#define MIN_HOLE 16781312
|
||||
#else
|
||||
/* Elsewhere we work with 4096*10 bytes */
|
||||
#define MIN_HOLE 409600
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <winioctl.h>
|
||||
/*
|
||||
@ -491,6 +499,7 @@ DEFINE_TEST(test_sparse_basic)
|
||||
{
|
||||
char *cwd;
|
||||
struct archive *a;
|
||||
const char *skip_sparse_tests;
|
||||
/*
|
||||
* The alignment of the hole of sparse files deeply depends
|
||||
* on filesystem. In my experience, sparse_file2 test with
|
||||
@ -501,42 +510,42 @@ DEFINE_TEST(test_sparse_basic)
|
||||
*/
|
||||
const struct sparse sparse_file0[] = {
|
||||
// 0 // 1024
|
||||
{ DATA, 1024 }, { HOLE, 2048000 },
|
||||
{ DATA, 1024 }, { HOLE, MIN_HOLE + 1638400 },
|
||||
// 2049024 // 2051072
|
||||
{ DATA, 2048 }, { HOLE, 2048000 },
|
||||
{ DATA, 2048 }, { HOLE, MIN_HOLE + 1638400 },
|
||||
// 4099072 // 4103168
|
||||
{ DATA, 4096 }, { HOLE, 20480000 },
|
||||
{ DATA, 4096 }, { HOLE, MIN_HOLE + 20070400 },
|
||||
// 24583168 // 24591360
|
||||
{ DATA, 8192 }, { HOLE, 204800000 },
|
||||
{ DATA, 8192 }, { HOLE, MIN_HOLE + 204390400 },
|
||||
// 229391360 // 229391361
|
||||
{ DATA, 1 }, { END, 0 }
|
||||
};
|
||||
const struct sparse sparse_file1[] = {
|
||||
{ HOLE, 409600 }, { DATA, 1 },
|
||||
{ HOLE, 409600 }, { DATA, 1 },
|
||||
{ HOLE, 409600 }, { END, 0 }
|
||||
{ HOLE, MIN_HOLE }, { DATA, 1 },
|
||||
{ HOLE, MIN_HOLE }, { DATA, 1 },
|
||||
{ HOLE, MIN_HOLE }, { END, 0 }
|
||||
};
|
||||
const struct sparse sparse_file2[] = {
|
||||
{ HOLE, 409600 * 1 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 2 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 3 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 4 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 5 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 6 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 7 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 8 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 9 }, { DATA, 1024 },
|
||||
{ HOLE, 409600 * 10}, { DATA, 1024 },/* 10 */
|
||||
{ HOLE, 409600 * 1 }, { DATA, 1024 * 1 },
|
||||
{ HOLE, 409600 * 2 }, { DATA, 1024 * 2 },
|
||||
{ HOLE, 409600 * 3 }, { DATA, 1024 * 3 },
|
||||
{ HOLE, 409600 * 4 }, { DATA, 1024 * 4 },
|
||||
{ HOLE, 409600 * 5 }, { DATA, 1024 * 5 },
|
||||
{ HOLE, 409600 * 6 }, { DATA, 1024 * 6 },
|
||||
{ HOLE, 409600 * 7 }, { DATA, 1024 * 7 },
|
||||
{ HOLE, 409600 * 8 }, { DATA, 1024 * 8 },
|
||||
{ HOLE, 409600 * 9 }, { DATA, 1024 * 9 },
|
||||
{ HOLE, 409600 * 10}, { DATA, 1024 * 10},/* 20 */
|
||||
{ HOLE, MIN_HOLE }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 1 }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 2 }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 3 }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 4 }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 5 }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 6 }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 7 }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 8 }, { DATA, 1024 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 9}, { DATA, 1024 },/* 10 */
|
||||
{ HOLE, MIN_HOLE }, { DATA, 1024 * 1 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 1 }, { DATA, 1024 * 2 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 2 }, { DATA, 1024 * 3 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 3 }, { DATA, 1024 * 4 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 4 }, { DATA, 1024 * 5 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 5 }, { DATA, 1024 * 6 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 6 }, { DATA, 1024 * 7 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 7 }, { DATA, 1024 * 8 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 8 }, { DATA, 1024 * 9 },
|
||||
{ HOLE, MIN_HOLE + 409600 * 9}, { DATA, 1024 * 10},/* 20 */
|
||||
{ END, 0 }
|
||||
};
|
||||
const struct sparse sparse_file3[] = {
|
||||
@ -553,6 +562,13 @@ DEFINE_TEST(test_sparse_basic)
|
||||
*/
|
||||
test_sparse_whole_file_data();
|
||||
|
||||
skip_sparse_tests = getenv("SKIP_TEST_SPARSE");
|
||||
if (skip_sparse_tests != NULL) {
|
||||
skipping("Skipping sparse tests due to SKIP_TEST_SPARSE "
|
||||
"environment variable");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the filesystem where CWD on can
|
||||
* report the number of the holes of a sparse file. */
|
||||
#ifdef PATH_MAX
|
||||
@ -599,10 +615,19 @@ DEFINE_TEST(test_fully_sparse_files)
|
||||
{
|
||||
char *cwd;
|
||||
struct archive *a;
|
||||
const char *skip_sparse_tests;
|
||||
|
||||
const struct sparse sparse_file[] = {
|
||||
{ HOLE, 409600 }, { END, 0 }
|
||||
{ HOLE, MIN_HOLE }, { END, 0 }
|
||||
};
|
||||
|
||||
skip_sparse_tests = getenv("SKIP_TEST_SPARSE");
|
||||
if (skip_sparse_tests != NULL) {
|
||||
skipping("Skipping sparse tests due to SKIP_TEST_SPARSE "
|
||||
"environment variable");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the filesystem where CWD on can
|
||||
* report the number of the holes of a sparse file. */
|
||||
#ifdef PATH_MAX
|
||||
|
@ -99,6 +99,139 @@ DEFINE_TEST(test_write_disk_symlink)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: dot -> . */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "dot");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, ".");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: dotdot -> .. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "dotdot");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "..");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: slash -> / */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "slash");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "/");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: sldot -> /. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "sldot");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "/.");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: sldotdot -> /.. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "sldotdot");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "/..");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Dir: d1 */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "d1");
|
||||
archive_entry_set_mode(ae, AE_IFDIR | 0777);
|
||||
archive_entry_unset_size(ae);
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: d1nosl -> d1 */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "d1nosl");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "d1");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: d1slash -> d1/ */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "d1slash");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "d1/");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: d1sldot -> d1/. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "d1sldot");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "d1/.");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: d1slddot -> d1/.. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "d1slddot");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "d1/..");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: d1dir -> d1 */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "d1dir");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_set_symlink_type(ae, AE_SYMLINK_TYPE_DIRECTORY);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "d1");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Symbolic link: d1file -> d1 */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, "d1file");
|
||||
archive_entry_set_mode(ae, AE_IFLNK | 0642);
|
||||
archive_entry_set_symlink_type(ae, AE_SYMLINK_TYPE_FILE);
|
||||
archive_entry_unset_size(ae);
|
||||
archive_entry_copy_symlink(ae, "d1");
|
||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
||||
if (r >= ARCHIVE_WARN)
|
||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
||||
archive_entry_free(ae);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(ad));
|
||||
|
||||
/* Test the entries on disk. */
|
||||
@ -107,11 +240,30 @@ DEFINE_TEST(test_write_disk_symlink)
|
||||
assertIsReg("link1a", -1);
|
||||
assertFileSize("link1a", sizeof(data));
|
||||
assertFileNLinks("link1a", 1);
|
||||
assertIsSymlink("link1b", "link1a");
|
||||
assertIsSymlink("link1b", "link1a", 0);
|
||||
|
||||
/* Test #2: Should produce identical results to test #1 */
|
||||
assertIsReg("link2a", -1);
|
||||
assertFileSize("link2a", sizeof(data));
|
||||
assertFileNLinks("link2a", 1);
|
||||
assertIsSymlink("link2b", "link2a");
|
||||
assertIsSymlink("link2b", "link2a", 0);
|
||||
|
||||
/* Test #3: Special symlinks */
|
||||
assertIsSymlink("dot", ".", 1);
|
||||
assertIsSymlink("dotdot", "..", 1);
|
||||
assertIsSymlink("slash", "/", 1);
|
||||
assertIsSymlink("sldot", "/.", 1);
|
||||
assertIsSymlink("sldotdot", "/..", 1);
|
||||
|
||||
/* Test #4: Directory symlink mixed with . and .. */
|
||||
assertIsDir("d1", -1);
|
||||
/* On Windows, d1nosl should be a file symlink */
|
||||
assertIsSymlink("d1nosl", "d1", 0);
|
||||
assertIsSymlink("d1slash", "d1/", 1);
|
||||
assertIsSymlink("d1sldot", "d1/.", 1);
|
||||
assertIsSymlink("d1slddot", "d1/..", 1);
|
||||
|
||||
/* Test #5: symlink_type is set */
|
||||
assertIsSymlink("d1dir", "d1", 1);
|
||||
assertIsSymlink("d1file", "d1", 0);
|
||||
}
|
||||
|
@ -204,6 +204,18 @@ Do not process files or directories that match the
|
||||
specified pattern.
|
||||
Note that exclusions take precedence over patterns or filenames
|
||||
specified on the command line.
|
||||
.It Fl Fl exclude-vcs
|
||||
Do not process files or directories internally used by the
|
||||
version control systems
|
||||
.Sq CVS ,
|
||||
.Sq RCS ,
|
||||
.Sq SCCS ,
|
||||
.Sq SVN ,
|
||||
.Sq Arch ,
|
||||
.Sq Bazaar ,
|
||||
.Sq Mercurial
|
||||
and
|
||||
.Sq Darcs .
|
||||
.It Fl Fl fflags
|
||||
(c, r, u, x modes only)
|
||||
Archive or extract file flags. This is the reverse of
|
||||
@ -386,8 +398,7 @@ and the default behavior in c, r, and u modes or if
|
||||
.Nm
|
||||
is run in x mode as root.
|
||||
.It Fl n , Fl Fl norecurse , Fl Fl no-recursion
|
||||
(c, r, u modes only)
|
||||
Do not recursively archive the contents of directories.
|
||||
Do not operate recursively on the content of directories.
|
||||
.It Fl Fl newer Ar date
|
||||
(c, r, u modes only)
|
||||
Only include files and directories newer than the specified date.
|
||||
|
@ -129,6 +129,28 @@ static void version(void) __LA_DEAD;
|
||||
(ARCHIVE_EXTRACT_SECURE_SYMLINKS \
|
||||
| ARCHIVE_EXTRACT_SECURE_NODOTDOT)
|
||||
|
||||
static char const * const vcs_files[] = {
|
||||
/* CVS */
|
||||
"CVS", ".cvsignore",
|
||||
/* RCS */
|
||||
"RCS",
|
||||
/* SCCS */
|
||||
"SCCS",
|
||||
/* SVN */
|
||||
".svn",
|
||||
/* git */
|
||||
".git", ".gitignore", ".gitattributes", ".gitmodules",
|
||||
/* Arch */
|
||||
".arch-ids", "{arch}", "=RELEASE-ID", "=meta-update", "=update",
|
||||
/* Bazaar */
|
||||
".bzr", ".bzrignore", ".bzrtags",
|
||||
/* Mercurial */
|
||||
".hg", ".hgignore", ".hgtags",
|
||||
/* darcs */
|
||||
"_darcs",
|
||||
NULL
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -318,6 +340,15 @@ main(int argc, char **argv)
|
||||
lafe_errc(1, 0,
|
||||
"Couldn't exclude %s\n", bsdtar->argument);
|
||||
break;
|
||||
case OPTION_EXCLUDE_VCS: /* GNU tar */
|
||||
for(t=0; vcs_files[t]; t++) {
|
||||
if (archive_match_exclude_pattern(
|
||||
bsdtar->matching,
|
||||
vcs_files[t]) != ARCHIVE_OK)
|
||||
lafe_errc(1, 0, "Couldn't "
|
||||
"exclude %s\n", vcs_files[t]);
|
||||
}
|
||||
break;
|
||||
case OPTION_FFLAGS:
|
||||
bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
|
||||
bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_FFLAGS;
|
||||
@ -808,8 +839,6 @@ main(int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bsdtar->flags & OPTFLAG_NO_SUBDIRS)
|
||||
only_mode(bsdtar, "-n", "cru");
|
||||
if (bsdtar->flags & OPTFLAG_STDOUT)
|
||||
only_mode(bsdtar, "-O", "xt");
|
||||
if (bsdtar->flags & OPTFLAG_UNLINK_FIRST)
|
||||
@ -859,6 +888,16 @@ main(int argc, char **argv)
|
||||
only_mode(bsdtar, buff, "cru");
|
||||
}
|
||||
|
||||
/*
|
||||
* When creating an archive from a directory tree, the directory
|
||||
* walking code will already avoid entering directories when
|
||||
* recursive inclusion of directory content is disabled, therefore
|
||||
* changing the matching behavior has no effect for creation modes.
|
||||
* It is relevant for extraction or listing.
|
||||
*/
|
||||
archive_match_set_inclusion_recursion(bsdtar->matching,
|
||||
!(bsdtar->flags & OPTFLAG_NO_SUBDIRS));
|
||||
|
||||
/* Filename "-" implies stdio. */
|
||||
if (strcmp(bsdtar->filename, "-") == 0)
|
||||
bsdtar->filename = NULL;
|
||||
|
@ -135,6 +135,7 @@ enum {
|
||||
OPTION_CHROOT,
|
||||
OPTION_CLEAR_NOCHANGE_FFLAGS,
|
||||
OPTION_EXCLUDE,
|
||||
OPTION_EXCLUDE_VCS,
|
||||
OPTION_FFLAGS,
|
||||
OPTION_FORMAT,
|
||||
OPTION_GID,
|
||||
|
@ -85,6 +85,7 @@ static const struct bsdtar_option {
|
||||
{ "disable-copyfile", 0, OPTION_NO_MAC_METADATA },
|
||||
{ "exclude", 1, OPTION_EXCLUDE },
|
||||
{ "exclude-from", 1, 'X' },
|
||||
{ "exclude-vcs", 0, OPTION_EXCLUDE_VCS },
|
||||
{ "extract", 0, 'x' },
|
||||
{ "fast-read", 0, 'q' },
|
||||
{ "fflags", 0, OPTION_FFLAGS },
|
||||
|
@ -42,7 +42,7 @@ make_files(void)
|
||||
|
||||
/* Symlink to above file. */
|
||||
if (canSymlink())
|
||||
assertMakeSymlink("symlink", "file");
|
||||
assertMakeSymlink("symlink", "file", 0);
|
||||
|
||||
/* Directory. */
|
||||
assertMakeDir("dir", 0775);
|
||||
@ -78,7 +78,7 @@ verify_files(const char *target)
|
||||
|
||||
/* Symlink */
|
||||
if (canSymlink())
|
||||
assertIsSymlink("symlink", "file");
|
||||
assertIsSymlink("symlink", "file", 0);
|
||||
|
||||
/* dir */
|
||||
failure("%s", target);
|
||||
|
@ -176,7 +176,7 @@ create_tree(void)
|
||||
sprintf(buff, "s/%s", filenames[i]);
|
||||
sprintf(buff2, "../f/%s", filenames[i]);
|
||||
failure("buff=\"%s\" buff2=\"%s\"", buff, buff2);
|
||||
assertMakeSymlink(buff, buff2);
|
||||
assertMakeSymlink(buff, buff2, 0);
|
||||
}
|
||||
/* Create a dir named "d/abcdef...". */
|
||||
buff[0] = 'd';
|
||||
@ -222,7 +222,7 @@ verify_tree(size_t limit)
|
||||
sprintf(name1, "s/%s", filenames[i]);
|
||||
sprintf(name2, "../f/%s", filenames[i]);
|
||||
if (strlen(name2) <= limit)
|
||||
assertIsSymlink(name1, name2);
|
||||
assertIsSymlink(name1, name2, 0);
|
||||
}
|
||||
|
||||
/* Verify dir "d/abcdef...". */
|
||||
|
@ -36,6 +36,9 @@ DEFINE_TEST(test_option_C_mtree)
|
||||
p0 = NULL;
|
||||
char *content = "./foo type=file uname=root gname=root mode=0755\n";
|
||||
char *filename = "output.tar";
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
char *p;
|
||||
#endif
|
||||
|
||||
/* an absolute path to mtree file */
|
||||
char *mtree_file = "/METALOG.mtree";
|
||||
@ -48,9 +51,21 @@ DEFINE_TEST(test_option_C_mtree)
|
||||
assertMakeDir("bar", 0775);
|
||||
assertMakeFile("bar/foo", 0777, "abc");
|
||||
|
||||
r = systemf("%s -cf %s -C bar \"@%s\" >step1.out 2>step1.err", testprog, filename, absolute_path);
|
||||
#if defined(_WIN32) && !defined(CYGWIN)
|
||||
p = absolute_path;
|
||||
while(*p != '\0') {
|
||||
if (*p == '/')
|
||||
*p = '\\';
|
||||
p++;
|
||||
}
|
||||
|
||||
r = systemf("%s -cf %s -C bar @%s >step1.out 2>step1.err", testprog, filename, absolute_path);
|
||||
failure("Error invoking %s -cf %s -C bar @%s", testprog, filename, absolute_path);
|
||||
#else
|
||||
r = systemf("%s -cf %s -C bar \"@%s\" >step1.out 2>step1.err", testprog, filename, absolute_path);
|
||||
failure("Error invoking %s -cf %s -C bar \"@%s\"", testprog, filename, absolute_path);
|
||||
#endif
|
||||
|
||||
assertEqualInt(r, 0);
|
||||
assertEmptyFile("step1.out");
|
||||
assertEmptyFile("step1.err");
|
||||
@ -68,6 +83,7 @@ DEFINE_TEST(test_option_C_mtree)
|
||||
assertEqualMem(p0 + 1536, "\0\0\0\0\0\0\0\0", 8);
|
||||
done:
|
||||
free(p0);
|
||||
free(absolute_path);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,13 +39,13 @@ DEFINE_TEST(test_option_H_upper)
|
||||
assertMakeDir("in", 0755);
|
||||
assertChdir("in");
|
||||
assertMakeDir("d1", 0755);
|
||||
assertMakeSymlink("ld1", "d1");
|
||||
assertMakeSymlink("ld1", "d1", 1);
|
||||
assertMakeFile("d1/file1", 0644, "d1/file1");
|
||||
assertMakeFile("d1/file2", 0644, "d1/file2");
|
||||
assertMakeSymlink("d1/link1", "file1");
|
||||
assertMakeSymlink("d1/linkX", "fileX");
|
||||
assertMakeSymlink("link2", "d1/file2");
|
||||
assertMakeSymlink("linkY", "d1/fileY");
|
||||
assertMakeSymlink("d1/link1", "file1", 0);
|
||||
assertMakeSymlink("d1/linkX", "fileX", 0);
|
||||
assertMakeSymlink("link2", "d1/file2", 0);
|
||||
assertMakeSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
|
||||
/* Test 1: Without -H */
|
||||
@ -55,11 +55,11 @@ DEFINE_TEST(test_option_H_upper)
|
||||
assertChdir("test1");
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
|
||||
assertIsSymlink("ld1", "d1");
|
||||
assertIsSymlink("d1/link1", "file1");
|
||||
assertIsSymlink("d1/linkX", "fileX");
|
||||
assertIsSymlink("link2", "d1/file2");
|
||||
assertIsSymlink("linkY", "d1/fileY");
|
||||
assertIsSymlink("ld1", "d1", 1);
|
||||
assertIsSymlink("d1/link1", "file1", 0);
|
||||
assertIsSymlink("d1/linkX", "fileX", 0);
|
||||
assertIsSymlink("link2", "d1/file2", 0);
|
||||
assertIsSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
|
||||
/* Test 2: With -H, no symlink on command line. */
|
||||
@ -69,11 +69,11 @@ DEFINE_TEST(test_option_H_upper)
|
||||
assertChdir("test2");
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
|
||||
assertIsSymlink("ld1", "d1");
|
||||
assertIsSymlink("d1/link1", "file1");
|
||||
assertIsSymlink("d1/linkX", "fileX");
|
||||
assertIsSymlink("link2", "d1/file2");
|
||||
assertIsSymlink("linkY", "d1/fileY");
|
||||
assertIsSymlink("ld1", "d1", 1);
|
||||
assertIsSymlink("d1/link1", "file1", 0);
|
||||
assertIsSymlink("d1/linkX", "fileX", 0);
|
||||
assertIsSymlink("link2", "d1/file2", 0);
|
||||
assertIsSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
|
||||
/* Test 3: With -H, some symlinks on command line. */
|
||||
@ -84,9 +84,9 @@ DEFINE_TEST(test_option_H_upper)
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
|
||||
assertIsDir("ld1", umasked(0755));
|
||||
assertIsSymlink("d1/linkX", "fileX");
|
||||
assertIsSymlink("d1/link1", "file1");
|
||||
assertIsSymlink("d1/linkX", "fileX", 0);
|
||||
assertIsSymlink("d1/link1", "file1", 0);
|
||||
assertIsReg("link2", umasked(0644));
|
||||
assertIsSymlink("linkY", "d1/fileY");
|
||||
assertIsSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
}
|
||||
|
@ -39,13 +39,13 @@ DEFINE_TEST(test_option_L_upper)
|
||||
assertMakeDir("in", 0755);
|
||||
assertChdir("in");
|
||||
assertMakeDir("d1", 0755);
|
||||
assertMakeSymlink("ld1", "d1");
|
||||
assertMakeSymlink("ld1", "d1", 1);
|
||||
assertMakeFile("d1/file1", 0644, "d1/file1");
|
||||
assertMakeFile("d1/file2", 0644, "d1/file2");
|
||||
assertMakeSymlink("d1/link1", "file1");
|
||||
assertMakeSymlink("d1/linkX", "fileX");
|
||||
assertMakeSymlink("link2", "d1/file2");
|
||||
assertMakeSymlink("linkY", "d1/fileY");
|
||||
assertMakeSymlink("d1/link1", "file1", 0);
|
||||
assertMakeSymlink("d1/linkX", "fileX", 0);
|
||||
assertMakeSymlink("link2", "d1/file2", 0);
|
||||
assertMakeSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
|
||||
/* Test 1: Without -L */
|
||||
@ -55,11 +55,11 @@ DEFINE_TEST(test_option_L_upper)
|
||||
assertChdir("test1");
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
|
||||
assertIsSymlink("ld1", "d1");
|
||||
assertIsSymlink("d1/link1", "file1");
|
||||
assertIsSymlink("d1/linkX", "fileX");
|
||||
assertIsSymlink("link2", "d1/file2");
|
||||
assertIsSymlink("linkY", "d1/fileY");
|
||||
assertIsSymlink("ld1", "d1", 1);
|
||||
assertIsSymlink("d1/link1", "file1", 0);
|
||||
assertIsSymlink("d1/linkX", "fileX", 0);
|
||||
assertIsSymlink("link2", "d1/file2", 0);
|
||||
assertIsSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
|
||||
/* Test 2: With -L, no symlink on command line. */
|
||||
@ -71,9 +71,9 @@ DEFINE_TEST(test_option_L_upper)
|
||||
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
|
||||
assertIsDir("ld1", umasked(0755));
|
||||
assertIsReg("d1/link1", umasked(0644));
|
||||
assertIsSymlink("d1/linkX", "fileX");
|
||||
assertIsSymlink("d1/linkX", "fileX", 0);
|
||||
assertIsReg("link2", umasked(0644));
|
||||
assertIsSymlink("linkY", "d1/fileY");
|
||||
assertIsSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
|
||||
/* Test 3: With -L, some symlinks on command line. */
|
||||
@ -85,8 +85,8 @@ DEFINE_TEST(test_option_L_upper)
|
||||
systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
|
||||
assertIsDir("ld1", umasked(0755));
|
||||
assertIsReg("d1/link1", umasked(0644));
|
||||
assertIsSymlink("d1/linkX", "fileX");
|
||||
assertIsSymlink("d1/linkX", "fileX", 0);
|
||||
assertIsReg("link2", umasked(0644));
|
||||
assertIsSymlink("linkY", "d1/fileY");
|
||||
assertIsSymlink("linkY", "d1/fileY", 0);
|
||||
assertChdir("..");
|
||||
}
|
||||
|
@ -79,10 +79,10 @@ DEFINE_TEST(test_option_U_upper)
|
||||
assertMakeDir("test3", 0755);
|
||||
assertChdir("test3");
|
||||
assertMakeDir("realDir", 0755);
|
||||
assertMakeSymlink("d1", "realDir");
|
||||
assertMakeSymlink("d1", "realDir", 1);
|
||||
r = systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog);
|
||||
assert(r != 0);
|
||||
assertIsSymlink("d1", "realDir");
|
||||
assertIsSymlink("d1", "realDir", 1);
|
||||
assertFileNotExists("d1/file1");
|
||||
assertEmptyFile("test.out");
|
||||
assertNonEmptyFile("test.err");
|
||||
@ -92,7 +92,7 @@ DEFINE_TEST(test_option_U_upper)
|
||||
assertMakeDir("test4", 0755);
|
||||
assertChdir("test4");
|
||||
assertMakeDir("realDir", 0755);
|
||||
assertMakeSymlink("d1", "realDir");
|
||||
assertMakeSymlink("d1", "realDir", 1);
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xUf ../archive.tar >test.out 2>test.err", testprog));
|
||||
assertIsDir("d1", -1);
|
||||
@ -105,10 +105,10 @@ DEFINE_TEST(test_option_U_upper)
|
||||
assertMakeDir("test5", 0755);
|
||||
assertChdir("test5");
|
||||
assertMakeDir("realDir", 0755);
|
||||
assertMakeSymlink("d1", "realDir");
|
||||
assertMakeSymlink("d1", "realDir", 1);
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xPf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
|
||||
assertIsSymlink("d1", "realDir");
|
||||
assertIsSymlink("d1", "realDir", 1);
|
||||
assertFileContents("d1/file1", 8, "d1/file1");
|
||||
assertEmptyFile("test.out");
|
||||
assertEmptyFile("test.err");
|
||||
@ -118,10 +118,10 @@ DEFINE_TEST(test_option_U_upper)
|
||||
assertMakeDir("test6", 0755);
|
||||
assertChdir("test6");
|
||||
assertMakeDir("realDir", 0755);
|
||||
assertMakeSymlink("d1", "realDir");
|
||||
assertMakeSymlink("d1", "realDir", 1);
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
|
||||
assertIsSymlink("d1", "realDir");
|
||||
assertIsSymlink("d1", "realDir", 1);
|
||||
assertFileContents("d1/file1", 8, "d1/file1");
|
||||
assertEmptyFile("test.out");
|
||||
assertEmptyFile("test.err");
|
||||
@ -132,7 +132,7 @@ DEFINE_TEST(test_option_U_upper)
|
||||
assertChdir("test7");
|
||||
assertMakeDir("d1", 0755);
|
||||
assertMakeFile("d1/realfile1", 0644, "realfile1");
|
||||
assertMakeSymlink("d1/file1", "d1/realfile1");
|
||||
assertMakeSymlink("d1/file1", "d1/realfile1", 0);
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
|
||||
assertIsReg("d1/file1", umasked(0644));
|
||||
@ -147,7 +147,7 @@ DEFINE_TEST(test_option_U_upper)
|
||||
assertChdir("test8");
|
||||
assertMakeDir("d1", 0755);
|
||||
assertMakeFile("d1/realfile1", 0644, "realfile1");
|
||||
assertMakeSymlink("d1/file1", "d1/realfile1");
|
||||
assertMakeSymlink("d1/file1", "d1/realfile1", 0);
|
||||
assertEqualInt(0,
|
||||
systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
|
||||
assertIsReg("d1/file1", umasked(0644));
|
||||
|
230
contrib/libarchive/tar/test/test_option_exclude_vcs.c
Normal file
230
contrib/libarchive/tar/test/test_option_exclude_vcs.c
Normal file
@ -0,0 +1,230 @@
|
||||
/*-
|
||||
* Copyright (c) 2019 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"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_exclude_vcs)
|
||||
{
|
||||
assertMakeDir("in", 0755);
|
||||
assertChdir("in");
|
||||
assertMakeFile("file", 0644, "");
|
||||
assertMakeDir("dir", 0755);
|
||||
assertMakeDir("CVS", 0755);
|
||||
assertMakeFile("CVS/fileattr", 0644, "");
|
||||
assertMakeFile(".cvsignore", 0644, "");
|
||||
assertMakeDir("RCS", 0755);
|
||||
assertMakeFile("RCS/somefile", 0655, "");
|
||||
assertMakeDir("SCCS", 0755);
|
||||
assertMakeFile("SCCS/somefile", 0655, "");
|
||||
assertMakeDir(".svn", 0755);
|
||||
assertMakeFile(".svn/format", 0655, "");
|
||||
assertMakeDir(".git", 0755);
|
||||
assertMakeFile(".git/config", 0655, "");
|
||||
assertMakeFile(".gitignore", 0644, "");
|
||||
assertMakeFile(".gitattributes", 0644, "");
|
||||
assertMakeFile(".gitmodules", 0644, "");
|
||||
assertMakeDir(".arch-ids", 0755);
|
||||
assertMakeFile(".arch-ids/somefile", 0644, "");
|
||||
assertMakeDir("{arch}", 0755);
|
||||
assertMakeFile("{arch}/somefile", 0644, "");
|
||||
assertMakeFile("=RELEASE-ID", 0644, "");
|
||||
assertMakeFile("=meta-update", 0644, "");
|
||||
assertMakeFile("=update", 0644, "");
|
||||
assertMakeDir(".bzr", 0755);
|
||||
assertMakeDir(".bzr/checkout", 0755);
|
||||
assertMakeFile(".bzrignore", 0644, "");
|
||||
assertMakeFile(".bzrtags", 0644, "");
|
||||
assertMakeDir(".hg", 0755);
|
||||
assertMakeFile(".hg/dirstate", 0644, "");
|
||||
assertMakeFile(".hgignore", 0644, "");
|
||||
assertMakeFile(".hgtags", 0644, "");
|
||||
assertMakeDir("_darcs", 0755);
|
||||
assertMakeFile("_darcs/format", 0644, "");
|
||||
assertChdir("..");
|
||||
|
||||
assertEqualInt(0, systemf("%s -c -C in -f included.tar .", testprog));
|
||||
assertEqualInt(0,
|
||||
systemf("%s -c --exclude-vcs -C in -f excluded.tar .", testprog));
|
||||
|
||||
/* No flags, archive with vcs files */
|
||||
assertMakeDir("vcs-noexclude", 0755);
|
||||
assertEqualInt(0, systemf("%s -x -C vcs-noexclude -f included.tar",
|
||||
testprog));
|
||||
assertChdir("vcs-noexclude");
|
||||
assertFileExists("file");
|
||||
assertIsDir("dir", 0755);
|
||||
assertIsDir("CVS", 0755);
|
||||
assertFileExists("CVS/fileattr");
|
||||
assertFileExists(".cvsignore");
|
||||
assertIsDir("RCS", 0755);
|
||||
assertFileExists("RCS/somefile");
|
||||
assertIsDir("SCCS", 0755);
|
||||
assertFileExists("SCCS/somefile");
|
||||
assertIsDir(".svn", 0755);
|
||||
assertFileExists(".svn/format");
|
||||
assertIsDir(".git", 0755);
|
||||
assertFileExists(".git/config");
|
||||
assertFileExists(".gitignore");
|
||||
assertFileExists(".gitattributes");
|
||||
assertFileExists(".gitmodules");
|
||||
assertIsDir(".arch-ids", 0755);
|
||||
assertFileExists(".arch-ids/somefile");
|
||||
assertIsDir("{arch}", 0755);
|
||||
assertFileExists("{arch}/somefile");
|
||||
assertFileExists("=RELEASE-ID");
|
||||
assertFileExists("=meta-update");
|
||||
assertFileExists("=update");
|
||||
assertIsDir(".bzr", 0755);
|
||||
assertIsDir(".bzr/checkout", 0755);
|
||||
assertFileExists(".bzrignore");
|
||||
assertFileExists(".bzrtags");
|
||||
assertIsDir(".hg", 0755);
|
||||
assertFileExists(".hg/dirstate");
|
||||
assertFileExists(".hgignore");
|
||||
assertFileExists(".hgtags");
|
||||
assertIsDir("_darcs", 0755);
|
||||
assertFileExists("_darcs/format");
|
||||
assertChdir("..");
|
||||
|
||||
/* --exclude-vcs, archive with vcs files */
|
||||
assertMakeDir("vcs-exclude", 0755);
|
||||
assertEqualInt(0,
|
||||
systemf("%s -x --exclude-vcs -C vcs-exclude -f included.tar", testprog));
|
||||
assertChdir("vcs-exclude");
|
||||
assertFileExists("file");
|
||||
assertIsDir("dir", 0755);
|
||||
assertFileNotExists("CVS");
|
||||
assertFileNotExists("CVS/fileattr");
|
||||
assertFileNotExists(".cvsignore");
|
||||
assertFileNotExists("RCS");
|
||||
assertFileNotExists("RCS/somefile");
|
||||
assertFileNotExists("SCCS");
|
||||
assertFileNotExists("SCCS/somefile");
|
||||
assertFileNotExists(".svn");
|
||||
assertFileNotExists(".svn/format");
|
||||
assertFileNotExists(".git");
|
||||
assertFileNotExists(".git/config");
|
||||
assertFileNotExists(".gitignore");
|
||||
assertFileNotExists(".gitattributes");
|
||||
assertFileNotExists(".gitmodules");
|
||||
assertFileNotExists(".arch-ids");
|
||||
assertFileNotExists(".arch-ids/somefile");
|
||||
assertFileNotExists("{arch}");
|
||||
assertFileNotExists("{arch}/somefile");
|
||||
assertFileNotExists("=RELEASE-ID");
|
||||
assertFileNotExists("=meta-update");
|
||||
assertFileNotExists("=update");
|
||||
assertFileNotExists(".bzr");
|
||||
assertFileNotExists(".bzr/checkout");
|
||||
assertFileNotExists(".bzrignore");
|
||||
assertFileNotExists(".bzrtags");
|
||||
assertFileNotExists(".hg");
|
||||
assertFileNotExists(".hg/dirstate");
|
||||
assertFileNotExists(".hgignore");
|
||||
assertFileNotExists(".hgtags");
|
||||
assertFileNotExists("_darcs");
|
||||
assertFileNotExists("_darcs/format");
|
||||
assertChdir("..");
|
||||
|
||||
/* --exclude-vcs, archive without vcs files */
|
||||
assertMakeDir("novcs-exclude", 0755);
|
||||
assertEqualInt(0,
|
||||
systemf("%s -x --exclude-vcs -C novcs-exclude -f excluded.tar",
|
||||
testprog));
|
||||
assertChdir("novcs-exclude");
|
||||
assertFileExists("file");
|
||||
assertIsDir("dir", 0755);
|
||||
assertFileNotExists("CVS");
|
||||
assertFileNotExists("CVS/fileattr");
|
||||
assertFileNotExists(".cvsignore");
|
||||
assertFileNotExists("RCS");
|
||||
assertFileNotExists("RCS/somefile");
|
||||
assertFileNotExists("SCCS");
|
||||
assertFileNotExists("SCCS/somefile");
|
||||
assertFileNotExists(".svn");
|
||||
assertFileNotExists(".svn/format");
|
||||
assertFileNotExists(".git");
|
||||
assertFileNotExists(".git/config");
|
||||
assertFileNotExists(".gitignore");
|
||||
assertFileNotExists(".gitattributes");
|
||||
assertFileNotExists(".gitmodules");
|
||||
assertFileNotExists(".arch-ids");
|
||||
assertFileNotExists(".arch-ids/somefile");
|
||||
assertFileNotExists("{arch}");
|
||||
assertFileNotExists("{arch}/somefile");
|
||||
assertFileNotExists("=RELEASE-ID");
|
||||
assertFileNotExists("=meta-update");
|
||||
assertFileNotExists("=update");
|
||||
assertFileNotExists(".bzr");
|
||||
assertFileNotExists(".bzr/checkout");
|
||||
assertFileNotExists(".bzrignore");
|
||||
assertFileNotExists(".bzrtags");
|
||||
assertFileNotExists(".hg");
|
||||
assertFileNotExists(".hg/dirstate");
|
||||
assertFileNotExists(".hgignore");
|
||||
assertFileNotExists(".hgtags");
|
||||
assertFileNotExists("_darcs");
|
||||
assertFileNotExists("_darcs/format");
|
||||
assertChdir("..");
|
||||
|
||||
/* No flags, archive without vcs files */
|
||||
assertMakeDir("novcs-noexclude", 0755);
|
||||
assertEqualInt(0,
|
||||
systemf("%s -x -C novcs-noexclude -f excluded.tar", testprog));
|
||||
assertChdir("novcs-noexclude");
|
||||
assertFileExists("file");
|
||||
assertIsDir("dir", 0755);
|
||||
assertFileNotExists("CVS");
|
||||
assertFileNotExists("CVS/fileattr");
|
||||
assertFileNotExists(".cvsignore");
|
||||
assertFileNotExists("RCS");
|
||||
assertFileNotExists("RCS/somefile");
|
||||
assertFileNotExists("SCCS");
|
||||
assertFileNotExists("SCCS/somefile");
|
||||
assertFileNotExists(".svn");
|
||||
assertFileNotExists(".svn/format");
|
||||
assertFileNotExists(".git");
|
||||
assertFileNotExists(".git/config");
|
||||
assertFileNotExists(".gitignore");
|
||||
assertFileNotExists(".gitattributes");
|
||||
assertFileNotExists(".gitmodules");
|
||||
assertFileNotExists(".arch-ids");
|
||||
assertFileNotExists(".arch-ids/somefile");
|
||||
assertFileNotExists("{arch}");
|
||||
assertFileNotExists("{arch}/somefile");
|
||||
assertFileNotExists("=RELEASE-ID");
|
||||
assertFileNotExists("=meta-update");
|
||||
assertFileNotExists("=update");
|
||||
assertFileNotExists(".bzr");
|
||||
assertFileNotExists(".bzr/checkout");
|
||||
assertFileNotExists(".bzrignore");
|
||||
assertFileNotExists(".bzrtags");
|
||||
assertFileNotExists(".hg");
|
||||
assertFileNotExists(".hg/dirstate");
|
||||
assertFileNotExists(".hgignore");
|
||||
assertFileNotExists(".hgtags");
|
||||
assertFileNotExists("_darcs");
|
||||
assertFileNotExists("_darcs/format");
|
||||
}
|
@ -25,8 +25,14 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
DEFINE_TEST(test_option_n)
|
||||
{
|
||||
int status;
|
||||
|
||||
assertMakeDir("d1", 0755);
|
||||
assertMakeFile("d1/file1", 0644, "d1/file1");
|
||||
|
||||
@ -58,4 +64,79 @@ DEFINE_TEST(test_option_n)
|
||||
assertIsDir("d1", umasked(0755));
|
||||
assertFileNotExists("d1/file1");
|
||||
assertChdir("..");
|
||||
|
||||
/*
|
||||
* Create a test archive with the following content:
|
||||
* d1/
|
||||
* d1/file1
|
||||
* d1/file2
|
||||
* file3
|
||||
* d2/file4
|
||||
*
|
||||
* Extracting uses the same code as listing and thus does not
|
||||
* get tested separately. This also covers the
|
||||
* archive_match_set_inclusion_recursion()
|
||||
* API.
|
||||
*/
|
||||
assertMakeFile("d1/file2", 0644, "d1/file2");
|
||||
assertMakeFile("file3", 0644, "file3");
|
||||
assertMakeDir("d2", 0755);
|
||||
assertMakeFile("d2/file4", 0644, "d2/file4");
|
||||
assertEqualInt(0,
|
||||
systemf("%s -cnf partial-archive.tar d1 d1/file1 d1/file2 file3 "
|
||||
"d2/file4 >c.out 2>c.err", testprog));
|
||||
|
||||
/* Test 3: -t without other options */
|
||||
assertEqualInt(0,
|
||||
systemf("%s -tf partial-archive.tar >test3.out 2>test3.err",
|
||||
testprog));
|
||||
assertEmptyFile("test3.err");
|
||||
assertTextFileContents("d1/\n"
|
||||
"d1/file1\n"
|
||||
"d1/file2\n"
|
||||
"file3\n"
|
||||
"d2/file4\n",
|
||||
"test3.out");
|
||||
|
||||
/* Test 4: -t without -n and some entries selected */
|
||||
assertEqualInt(0,
|
||||
systemf("%s -tf partial-archive.tar d1 file3 d2/file4 "
|
||||
">test4.out 2>test4.err", testprog));
|
||||
assertEmptyFile("test4.err");
|
||||
assertTextFileContents("d1/\n"
|
||||
"d1/file1\n"
|
||||
"d1/file2\n"
|
||||
"file3\n"
|
||||
"d2/file4\n",
|
||||
"test4.out");
|
||||
|
||||
/* Test 5: -t with -n and some entries selected */
|
||||
assertEqualInt(0,
|
||||
systemf("%s -tnf partial-archive.tar d1 file3 d2/file4 "
|
||||
">test5.out 2>test5.err", testprog));
|
||||
assertEmptyFile("test5.err");
|
||||
assertTextFileContents("d1/\n"
|
||||
"file3\n"
|
||||
"d2/file4\n",
|
||||
"test5.out");
|
||||
|
||||
/* Test 6: -t without -n and non-existant directory selected */
|
||||
assertEqualInt(0,
|
||||
systemf("%s -tf partial-archive.tar d2 >test6.out 2>test6.err",
|
||||
testprog));
|
||||
assertEmptyFile("test6.err");
|
||||
assertTextFileContents("d2/file4\n",
|
||||
"test6.out");
|
||||
|
||||
/* Test 7: -t with -n and non-existant directory selected */
|
||||
status = systemf("%s -tnf partial-archive.tar d2 "
|
||||
">test7.out 2>test7.err", testprog);
|
||||
assert(status);
|
||||
assert(status != -1);
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
assert(WIFEXITED(status));
|
||||
assertEqualInt(1, WEXITSTATUS(status));
|
||||
#endif
|
||||
assertNonEmptyFile("test7.err");
|
||||
assertEmptyFile("test7.out");
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ DEFINE_TEST(test_option_s)
|
||||
assertMakeFile("in/d1/bar", 0644, "bar");
|
||||
if (canSymlink()) {
|
||||
assertMakeFile("in/d1/realfile", 0644, "realfile");
|
||||
assertMakeSymlink("in/d1/symlink", "realfile");
|
||||
assertMakeSymlink("in/d1/symlink", "realfile", 0);
|
||||
}
|
||||
assertMakeFile("in/d1/hardlink1", 0644, "hardlinkedfile");
|
||||
assertMakeHardlink("in/d1/hardlink2", "in/d1/hardlink1");
|
||||
@ -109,14 +109,14 @@ DEFINE_TEST(test_option_s)
|
||||
testprog, testprog);
|
||||
assertFileContents("realfile", 8, "test6a/in/d2/realfile");
|
||||
assertFileContents("realfile", 8, "test6a/in/d2/symlink");
|
||||
assertIsSymlink("test6a/in/d2/symlink", "realfile");
|
||||
assertIsSymlink("test6a/in/d2/symlink", "realfile", 0);
|
||||
/* At creation time. */
|
||||
assertMakeDir("test6b", 0755);
|
||||
systemf("%s -cf - -s /d1/d2/ in/d1 | %s -xf - -C test6b",
|
||||
testprog, testprog);
|
||||
assertFileContents("realfile", 8, "test6b/in/d2/realfile");
|
||||
assertFileContents("realfile", 8, "test6b/in/d2/symlink");
|
||||
assertIsSymlink("test6b/in/d2/symlink", "realfile");
|
||||
assertIsSymlink("test6b/in/d2/symlink", "realfile", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,14 +129,14 @@ DEFINE_TEST(test_option_s)
|
||||
testprog, testprog);
|
||||
assertFileContents("realfile", 8, "test7a/in/d1/realfile-renamed");
|
||||
assertFileContents("realfile", 8, "test7a/in/d1/symlink");
|
||||
assertIsSymlink("test7a/in/d1/symlink", "realfile-renamed");
|
||||
assertIsSymlink("test7a/in/d1/symlink", "realfile-renamed", 0);
|
||||
/* At creation. */
|
||||
assertMakeDir("test7b", 0755);
|
||||
systemf("%s -cf - -s /realfile/realfile-renamed/ in/d1 | %s -xf - -C test7b",
|
||||
testprog, testprog);
|
||||
assertFileContents("realfile", 8, "test7b/in/d1/realfile-renamed");
|
||||
assertFileContents("realfile", 8, "test7b/in/d1/symlink");
|
||||
assertIsSymlink("test7b/in/d1/symlink", "realfile-renamed");
|
||||
assertIsSymlink("test7b/in/d1/symlink", "realfile-renamed", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -192,7 +192,7 @@ DEFINE_TEST(test_option_s)
|
||||
assertFileContents("realfile", 8, "test10a/in/d1/foo");
|
||||
assertFileContents("foo", 3, "test10a/in/d1/realfile");
|
||||
assertFileContents("foo", 3, "test10a/in/d1/symlink");
|
||||
assertIsSymlink("test10a/in/d1/symlink", "realfile");
|
||||
assertIsSymlink("test10a/in/d1/symlink", "realfile", 0);
|
||||
/* At creation. */
|
||||
assertMakeDir("test10b", 0755);
|
||||
systemf("%s -cf - -s /realfile/foo/S -s /foo/realfile/ in/d1 | %s -xf - -C test10b",
|
||||
@ -200,7 +200,7 @@ DEFINE_TEST(test_option_s)
|
||||
assertFileContents("realfile", 8, "test10b/in/d1/foo");
|
||||
assertFileContents("foo", 3, "test10b/in/d1/realfile");
|
||||
assertFileContents("foo", 3, "test10b/in/d1/symlink");
|
||||
assertIsSymlink("test10b/in/d1/symlink", "realfile");
|
||||
assertIsSymlink("test10b/in/d1/symlink", "realfile", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -214,7 +214,7 @@ DEFINE_TEST(test_option_s)
|
||||
assertFileContents("foo", 3, "test11a/in/d1/foo");
|
||||
assertFileContents("realfile", 8, "test11a/in/d1/realfile");
|
||||
assertFileContents("foo", 3, "test11a/in/d1/symlink");
|
||||
assertIsSymlink("test11a/in/d1/symlink", "foo");
|
||||
assertIsSymlink("test11a/in/d1/symlink", "foo", 0);
|
||||
/* At creation. */
|
||||
assertMakeDir("test11b", 0755);
|
||||
systemf("%s -cf - -s /realfile/foo/R in/d1 | %s -xf - -C test11b",
|
||||
@ -222,7 +222,7 @@ DEFINE_TEST(test_option_s)
|
||||
assertFileContents("foo", 3, "test11b/in/d1/foo");
|
||||
assertFileContents("realfile", 8, "test11b/in/d1/realfile");
|
||||
assertFileContents("foo", 3, "test11b/in/d1/symlink");
|
||||
assertIsSymlink("test11b/in/d1/symlink", "foo");
|
||||
assertIsSymlink("test11b/in/d1/symlink", "foo", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -36,8 +36,8 @@ DEFINE_TEST(test_strip_components)
|
||||
assertMakeHardlink("l1", "d1/d2/f1");
|
||||
assertMakeHardlink("d1/l2", "d1/d2/f1");
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("s1", "d1/d2/f1");
|
||||
assertMakeSymlink("d1/s2", "d2/f1");
|
||||
assertMakeSymlink("s1", "d1/d2/f1", 0);
|
||||
assertMakeSymlink("d1/s2", "d2/f1", 0);
|
||||
}
|
||||
assertChdir("..");
|
||||
|
||||
@ -64,9 +64,10 @@ DEFINE_TEST(test_strip_components)
|
||||
failure("d0/d1/s2 is a symlink to something that won't be extracted");
|
||||
/* If platform supports symlinks, target/s2 is a broken symlink. */
|
||||
/* If platform does not support symlink, target/s2 doesn't exist. */
|
||||
assertFileNotExists("target/s2");
|
||||
if (canSymlink())
|
||||
assertIsSymlink("target/s2", "d2/f1");
|
||||
assertIsSymlink("target/s2", "d2/f1", 0);
|
||||
else
|
||||
assertFileNotExists("target/s2");
|
||||
failure("d0/d1/d2 should be extracted");
|
||||
assertIsDir("target/d2", -1);
|
||||
|
||||
@ -122,7 +123,7 @@ DEFINE_TEST(test_strip_components)
|
||||
/* If platform supports symlinks, target/s2 is included. */
|
||||
if (canSymlink()) {
|
||||
failure("d0/d1/s2 is a symlink to something included in archive");
|
||||
assertIsSymlink("target2/s2", "d2/f1");
|
||||
assertIsSymlink("target2/s2", "d2/f1", 0);
|
||||
}
|
||||
failure("d0/d1/d2 should be archived");
|
||||
assertIsDir("target2/d2", -1);
|
||||
|
@ -66,22 +66,22 @@ DEFINE_TEST(test_symlink_dir)
|
||||
/* "dir" is a symlink to an existing "dest1/real_dir" */
|
||||
assertMakeDir("dest1/real_dir", 0755);
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("dest1/dir", "real_dir");
|
||||
assertMakeSymlink("dest1/dir", "real_dir", 1);
|
||||
/* "dir2" is a symlink to a non-existing "real_dir2" */
|
||||
assertMakeSymlink("dest1/dir2", "real_dir2");
|
||||
assertMakeSymlink("dest1/dir2", "real_dir2", 1);
|
||||
} else {
|
||||
skipping("Symlinks are not supported on this platform");
|
||||
}
|
||||
/* "dir3" is a symlink to an existing "non_dir3" */
|
||||
assertMakeFile("dest1/non_dir3", 0755, "abcdef");
|
||||
if (canSymlink())
|
||||
assertMakeSymlink("dest1/dir3", "non_dir3");
|
||||
assertMakeSymlink("dest1/dir3", "non_dir3", 1);
|
||||
/* "file" is a symlink to existing "real_file" */
|
||||
assertMakeFile("dest1/real_file", 0755, "abcdefg");
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("dest1/file", "real_file");
|
||||
assertMakeSymlink("dest1/file", "real_file", 0);
|
||||
/* "file2" is a symlink to non-existing "real_file2" */
|
||||
assertMakeSymlink("dest1/file2", "real_file2");
|
||||
assertMakeSymlink("dest1/file2", "real_file2", 0);
|
||||
}
|
||||
assertEqualInt(0, systemf("%s -xf test.tar -C dest1", testprog));
|
||||
|
||||
@ -108,32 +108,32 @@ DEFINE_TEST(test_symlink_dir)
|
||||
/* "dir" is a symlink to existing "real_dir" */
|
||||
assertMakeDir("dest2/real_dir", 0755);
|
||||
if (canSymlink())
|
||||
assertMakeSymlink("dest2/dir", "real_dir");
|
||||
assertMakeSymlink("dest2/dir", "real_dir", 1);
|
||||
/* "dir2" is a symlink to a non-existing "real_dir2" */
|
||||
if (canSymlink())
|
||||
assertMakeSymlink("dest2/dir2", "real_dir2");
|
||||
assertMakeSymlink("dest2/dir2", "real_dir2", 1);
|
||||
/* "dir3" is a symlink to an existing "non_dir3" */
|
||||
assertMakeFile("dest2/non_dir3", 0755, "abcdefgh");
|
||||
if (canSymlink())
|
||||
assertMakeSymlink("dest2/dir3", "non_dir3");
|
||||
assertMakeSymlink("dest2/dir3", "non_dir3", 1);
|
||||
/* "file" is a symlink to existing "real_file" */
|
||||
assertMakeFile("dest2/real_file", 0755, "abcdefghi");
|
||||
if (canSymlink())
|
||||
assertMakeSymlink("dest2/file", "real_file");
|
||||
assertMakeSymlink("dest2/file", "real_file", 0);
|
||||
/* "file2" is a symlink to non-existing "real_file2" */
|
||||
if (canSymlink())
|
||||
assertMakeSymlink("dest2/file2", "real_file2");
|
||||
assertMakeSymlink("dest2/file2", "real_file2", 0);
|
||||
assertEqualInt(0, systemf("%s -xPf test.tar -C dest2", testprog));
|
||||
|
||||
/* "dir4" is a symlink to existing "real_dir" */
|
||||
if (canSymlink())
|
||||
assertMakeSymlink("dest2/dir4", "real_dir");
|
||||
assertMakeSymlink("dest2/dir4", "real_dir", 1);
|
||||
assertEqualInt(0, systemf("%s -xPf test2.tar -C dest2", testprog));
|
||||
|
||||
/* dest2/dir and dest2/dir4 symlinks should be followed */
|
||||
if (canSymlink()) {
|
||||
assertIsSymlink("dest2/dir", "real_dir");
|
||||
assertIsSymlink("dest2/dir4", "real_dir");
|
||||
assertIsSymlink("dest2/dir", "real_dir", 1);
|
||||
assertIsSymlink("dest2/dir4", "real_dir", 1);
|
||||
assertIsDir("dest2/real_dir", -1);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,9 @@
|
||||
#include <sys/richacl.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#define NOCRYPT
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -218,8 +220,8 @@
|
||||
assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
|
||||
#define assertIsReg(pathname, mode) \
|
||||
assertion_is_reg(__FILE__, __LINE__, pathname, mode)
|
||||
#define assertIsSymlink(pathname, contents) \
|
||||
assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
|
||||
#define assertIsSymlink(pathname, contents, isdir) \
|
||||
assertion_is_symlink(__FILE__, __LINE__, pathname, contents, isdir)
|
||||
/* Create a directory, report error if it fails. */
|
||||
#define assertMakeDir(dirname, mode) \
|
||||
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
|
||||
@ -229,8 +231,8 @@
|
||||
assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
|
||||
#define assertMakeHardlink(newfile, oldfile) \
|
||||
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
|
||||
#define assertMakeSymlink(newfile, linkto) \
|
||||
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
|
||||
#define assertMakeSymlink(newfile, linkto, targetIsDir) \
|
||||
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto, targetIsDir)
|
||||
#define assertSetNodump(path) \
|
||||
assertion_set_nodump(__FILE__, __LINE__, path)
|
||||
#define assertUmask(mask) \
|
||||
@ -287,11 +289,11 @@ int assertion_is_dir(const char *, int, const char *, int);
|
||||
int assertion_is_hardlink(const char *, int, const char *, const char *);
|
||||
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
|
||||
int assertion_is_reg(const char *, int, const char *, int);
|
||||
int assertion_is_symlink(const char *, int, const char *, const char *);
|
||||
int assertion_is_symlink(const char *, int, const char *, const char *, int);
|
||||
int assertion_make_dir(const char *, int, const char *, int);
|
||||
int assertion_make_file(const char *, int, const char *, int, int, const void *);
|
||||
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
|
||||
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
|
||||
int assertion_make_symlink(const char *, int, const char *newpath, const char *, int);
|
||||
int assertion_non_empty_file(const char *, int, const char *);
|
||||
int assertion_set_nodump(const char *, int, const char *);
|
||||
int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
|
||||
|
@ -168,6 +168,32 @@ static int my_CreateHardLinkA(const char *, const char *);
|
||||
static int my_GetFileInformationByName(const char *,
|
||||
BY_HANDLE_FILE_INFORMATION *);
|
||||
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
ULONG Flags;
|
||||
WCHAR PathBuffer[1];
|
||||
} SymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} MountPointReparseBuffer;
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
} DUMMYUNIONNAME;
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
static void *
|
||||
GetFunctionKernel32(const char *name)
|
||||
{
|
||||
@ -185,15 +211,101 @@ GetFunctionKernel32(const char *name)
|
||||
}
|
||||
|
||||
static int
|
||||
my_CreateSymbolicLinkA(const char *linkname, const char *target, int flags)
|
||||
my_CreateSymbolicLinkA(const char *linkname, const char *target,
|
||||
int targetIsDir)
|
||||
{
|
||||
static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, DWORD);
|
||||
DWORD attrs;
|
||||
static int set;
|
||||
int ret, tmpflags, llen, tlen;
|
||||
int flags = 0;
|
||||
char *src, *tgt, *p;
|
||||
if (!set) {
|
||||
set = 1;
|
||||
f = GetFunctionKernel32("CreateSymbolicLinkA");
|
||||
}
|
||||
return f == NULL ? 0 : (*f)(linkname, target, flags);
|
||||
if (f == NULL)
|
||||
return (0);
|
||||
|
||||
tlen = strlen(target);
|
||||
llen = strlen(linkname);
|
||||
|
||||
if (tlen == 0 || llen == 0)
|
||||
return (0);
|
||||
|
||||
tgt = malloc((tlen + 1) * sizeof(char));
|
||||
if (tgt == NULL)
|
||||
return (0);
|
||||
src = malloc((llen + 1) * sizeof(char));
|
||||
if (src == NULL) {
|
||||
free(tgt);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate slashes to backslashes
|
||||
*/
|
||||
p = src;
|
||||
while(*linkname != '\0') {
|
||||
if (*linkname == '/')
|
||||
*p = '\\';
|
||||
else
|
||||
*p = *linkname;
|
||||
linkname++;
|
||||
p++;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
p = tgt;
|
||||
while(*target != '\0') {
|
||||
if (*target == '/')
|
||||
*p = '\\';
|
||||
else
|
||||
*p = *target;
|
||||
target++;
|
||||
p++;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
/*
|
||||
* Each test has to specify if a file or a directory symlink
|
||||
* should be created.
|
||||
*/
|
||||
if (targetIsDir) {
|
||||
#if defined(SYMBOLIC_LINK_FLAG_DIRECTORY)
|
||||
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
|
||||
#else
|
||||
flags |= 0x1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
|
||||
tmpflags = flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
|
||||
#else
|
||||
tmpflags = flags | 0x2;
|
||||
#endif
|
||||
/*
|
||||
* Windows won't overwrite existing links
|
||||
*/
|
||||
attrs = GetFileAttributesA(linkname);
|
||||
if (attrs != INVALID_FILE_ATTRIBUTES) {
|
||||
if (attrs & FILE_ATTRIBUTE_DIRECTORY)
|
||||
RemoveDirectoryA(linkname);
|
||||
else
|
||||
DeleteFileA(linkname);
|
||||
}
|
||||
|
||||
ret = (*f)(src, tgt, tmpflags);
|
||||
/*
|
||||
* Prior to Windows 10 the SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
|
||||
* is not undestood
|
||||
*/
|
||||
if (!ret)
|
||||
ret = (*f)(src, tgt, flags);
|
||||
|
||||
free(src);
|
||||
free(tgt);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1599,26 +1711,146 @@ assertion_is_reg(const char *file, int line, const char *pathname, int mode)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Check whether 'pathname' is a symbolic link. If 'contents' is
|
||||
* non-NULL, verify that the symlink has those contents. */
|
||||
/*
|
||||
* Check whether 'pathname' is a symbolic link. If 'contents' is
|
||||
* non-NULL, verify that the symlink has those contents.
|
||||
*
|
||||
* On platforms with directory symlinks, set isdir to 0 to test for a file
|
||||
* symlink and to 1 to test for a directory symlink. On other platforms
|
||||
* the variable is ignored.
|
||||
*/
|
||||
static int
|
||||
is_symlink(const char *file, int line,
|
||||
const char *pathname, const char *contents)
|
||||
const char *pathname, const char *contents, int isdir)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
(void)pathname; /* UNUSED */
|
||||
(void)contents; /* UNUSED */
|
||||
assertion_count(file, line);
|
||||
/* Windows sort-of has real symlinks, but they're only usable
|
||||
* by privileged users and are crippled even then, so there's
|
||||
* really not much point in bothering with this. */
|
||||
return (0);
|
||||
HANDLE h;
|
||||
DWORD inbytes;
|
||||
REPARSE_DATA_BUFFER *buf;
|
||||
BY_HANDLE_FILE_INFORMATION st;
|
||||
size_t len, len2;
|
||||
wchar_t *linknamew, *contentsw;
|
||||
const char *p;
|
||||
char *s, *pn;
|
||||
int ret = 0;
|
||||
BYTE *indata;
|
||||
const DWORD flag = FILE_FLAG_BACKUP_SEMANTICS |
|
||||
FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
|
||||
/* Replace slashes with backslashes in pathname */
|
||||
pn = malloc((strlen(pathname) + 1) * sizeof(char));
|
||||
p = pathname;
|
||||
s = pn;
|
||||
while(*p != '\0') {
|
||||
if(*p == '/')
|
||||
*s = '\\';
|
||||
else
|
||||
*s = *p;
|
||||
p++;
|
||||
s++;
|
||||
}
|
||||
*s = '\0';
|
||||
|
||||
h = CreateFileA(pn, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
flag, NULL);
|
||||
free(pn);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
failure_start(file, line, "Can't access %s\n", pathname);
|
||||
failure_finish(NULL);
|
||||
return (0);
|
||||
}
|
||||
ret = GetFileInformationByHandle(h, &st);
|
||||
if (ret == 0) {
|
||||
failure_start(file, line,
|
||||
"Can't stat: %s", pathname);
|
||||
failure_finish(NULL);
|
||||
} else if ((st.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
|
||||
failure_start(file, line,
|
||||
"Not a symlink: %s", pathname);
|
||||
failure_finish(NULL);
|
||||
ret = 0;
|
||||
}
|
||||
if (isdir && ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
|
||||
failure_start(file, line,
|
||||
"Not a directory symlink: %s", pathname);
|
||||
failure_finish(NULL);
|
||||
ret = 0;
|
||||
}
|
||||
if (!isdir &&
|
||||
((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) {
|
||||
failure_start(file, line,
|
||||
"Not a file symlink: %s", pathname);
|
||||
failure_finish(NULL);
|
||||
ret = 0;
|
||||
}
|
||||
if (ret == 0) {
|
||||
CloseHandle(h);
|
||||
return (0);
|
||||
}
|
||||
|
||||
indata = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
||||
ret = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, indata,
|
||||
1024, &inbytes, NULL);
|
||||
CloseHandle(h);
|
||||
if (ret == 0) {
|
||||
free(indata);
|
||||
failure_start(file, line,
|
||||
"Could not retrieve symlink target: %s", pathname);
|
||||
failure_finish(NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
buf = (REPARSE_DATA_BUFFER *) indata;
|
||||
if (buf->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
|
||||
free(indata);
|
||||
/* File is not a symbolic link */
|
||||
failure_start(file, line,
|
||||
"Not a symlink: %s", pathname);
|
||||
failure_finish(NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (contents == NULL) {
|
||||
free(indata);
|
||||
return (1);
|
||||
}
|
||||
|
||||
len = buf->SymbolicLinkReparseBuffer.SubstituteNameLength;
|
||||
|
||||
linknamew = malloc(len + sizeof(wchar_t));
|
||||
if (linknamew == NULL) {
|
||||
free(indata);
|
||||
return (0);
|
||||
}
|
||||
|
||||
memcpy(linknamew, &((BYTE *)buf->SymbolicLinkReparseBuffer.PathBuffer)
|
||||
[buf->SymbolicLinkReparseBuffer.SubstituteNameOffset], len);
|
||||
free(indata);
|
||||
|
||||
linknamew[len / sizeof(wchar_t)] = L'\0';
|
||||
|
||||
contentsw = malloc(len + sizeof(wchar_t));
|
||||
if (contentsw == NULL) {
|
||||
free(linknamew);
|
||||
return (0);
|
||||
}
|
||||
|
||||
len2 = mbsrtowcs(contentsw, &contents, (len + sizeof(wchar_t)
|
||||
/ sizeof(wchar_t)), NULL);
|
||||
|
||||
if (len2 > 0 && wcscmp(linknamew, contentsw) != 0)
|
||||
ret = 1;
|
||||
|
||||
free(linknamew);
|
||||
free(contentsw);
|
||||
return (ret);
|
||||
#else
|
||||
char buff[300];
|
||||
struct stat st;
|
||||
ssize_t linklen;
|
||||
int r;
|
||||
|
||||
(void)isdir; /* UNUSED */
|
||||
assertion_count(file, line);
|
||||
r = lstat(pathname, &st);
|
||||
if (r != 0) {
|
||||
@ -1647,9 +1879,9 @@ is_symlink(const char *file, int line,
|
||||
/* Assert that path is a symlink that (optionally) contains contents. */
|
||||
int
|
||||
assertion_is_symlink(const char *file, int line,
|
||||
const char *path, const char *contents)
|
||||
const char *path, const char *contents, int isdir)
|
||||
{
|
||||
if (is_symlink(file, line, path, contents))
|
||||
if (is_symlink(file, line, path, contents, isdir))
|
||||
return (1);
|
||||
if (contents)
|
||||
failure_start(file, line, "File %s is not a symlink to %s",
|
||||
@ -1777,20 +2009,26 @@ assertion_make_hardlink(const char *file, int line,
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Create a symlink and report any failures. */
|
||||
/*
|
||||
* Create a symlink and report any failures.
|
||||
*
|
||||
* Windows symlinks need to know if the target is a directory.
|
||||
*/
|
||||
int
|
||||
assertion_make_symlink(const char *file, int line,
|
||||
const char *newpath, const char *linkto)
|
||||
const char *newpath, const char *linkto, int targetIsDir)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
int targetIsDir = 0; /* TODO: Fix this */
|
||||
assertion_count(file, line);
|
||||
if (my_CreateSymbolicLinkA(newpath, linkto, targetIsDir))
|
||||
return (1);
|
||||
#elif HAVE_SYMLINK
|
||||
(void)targetIsDir; /* UNUSED */
|
||||
assertion_count(file, line);
|
||||
if (0 == symlink(linkto, newpath))
|
||||
return (1);
|
||||
#else
|
||||
(void)targetIsDir; /* UNUSED */
|
||||
#endif
|
||||
failure_start(file, line, "Could not create symlink");
|
||||
logprintf(" New link: %s\n", newpath);
|
||||
@ -2217,10 +2455,12 @@ canSymlink(void)
|
||||
* use the Win32 CreateSymbolicLink() function. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
value = my_CreateSymbolicLinkA("canSymlink.1", "canSymlink.0", 0)
|
||||
&& is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0");
|
||||
&& is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0",
|
||||
0);
|
||||
#elif HAVE_SYMLINK
|
||||
value = (0 == symlink("canSymlink.0", "canSymlink.1"))
|
||||
&& is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0");
|
||||
&& is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0",
|
||||
0);
|
||||
#endif
|
||||
return (value);
|
||||
}
|
||||
|
@ -168,6 +168,7 @@ SRCS= archive_acl.c \
|
||||
MAN= archive_entry.3 \
|
||||
archive_entry_acl.3 \
|
||||
archive_entry_linkify.3 \
|
||||
archive_entry_misc.3 \
|
||||
archive_entry_paths.3 \
|
||||
archive_entry_perms.3 \
|
||||
archive_entry_stat.3 \
|
||||
|
@ -169,6 +169,7 @@ TESTS_SRCS= \
|
||||
test_read_format_tar_concatenated.c \
|
||||
test_read_format_tar_empty_filename.c \
|
||||
test_read_format_tar_empty_pax.c \
|
||||
test_read_format_tar_empty_with_gnulabel.c \
|
||||
test_read_format_tar_filename.c \
|
||||
test_read_format_tbz.c \
|
||||
test_read_format_tgz.c \
|
||||
@ -179,10 +180,12 @@ TESTS_SRCS= \
|
||||
test_read_format_warc.c \
|
||||
test_read_format_xar.c \
|
||||
test_read_format_zip.c \
|
||||
test_read_format_zip_7075_utf8_paths.c \
|
||||
test_read_format_zip_comment_stored.c \
|
||||
test_read_format_zip_encryption_data.c \
|
||||
test_read_format_zip_encryption_header.c \
|
||||
test_read_format_zip_encryption_partially.c \
|
||||
test_read_format_zip_extra_padding.c \
|
||||
test_read_format_zip_filename.c \
|
||||
test_read_format_zip_high_compression.c \
|
||||
test_read_format_zip_jar.c \
|
||||
@ -486,6 +489,7 @@ ${PACKAGE}FILES+= test_read_format_mtree_crash747.mtree.bz2.uu
|
||||
${PACKAGE}FILES+= test_read_format_mtree_nomagic.mtree.uu
|
||||
${PACKAGE}FILES+= test_read_format_mtree_nomagic2.mtree.uu
|
||||
${PACKAGE}FILES+= test_read_format_mtree_nomagic3.mtree.uu
|
||||
${PACKAGE}FILES+= test_read_format_mtree_noprint.mtree.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_binary_data.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_compress_best.rar.uu
|
||||
@ -501,6 +505,7 @@ ${PACKAGE}FILES+= test_read_format_rar_multivolume.part0003.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_multivolume.part0004.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_noeof.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_ppmd_lzss_conversion.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_ppmd_use_after_free.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_sfx.exe.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_subblock.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar_unicode.rar.uu
|
||||
@ -508,6 +513,13 @@ ${PACKAGE}FILES+= test_read_format_rar_windows.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_arm.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_blake2.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_compressed.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_distance_overflow.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_extra_field_version.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_fileattr.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_hardlink.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_invalid_dict_reference.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_leftshift1.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_leftshift2.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_multiarchive.part01.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_multiarchive.part02.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_multiarchive.part03.rar.uu
|
||||
@ -522,15 +534,22 @@ ${PACKAGE}FILES+= test_read_format_rar5_multiarchive_solid.part03.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_multiarchive_solid.part04.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_multiple_files.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_multiple_files_solid.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_nonempty_dir_stream.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_owner.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_readtables_overflow.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_solid.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_stored.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_stored_manyfiles.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_symlink.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_truncated_huff.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_rar5_win32.rar.uu
|
||||
${PACKAGE}FILES+= test_read_format_raw.bufr.uu
|
||||
${PACKAGE}FILES+= test_read_format_raw.data.Z.uu
|
||||
${PACKAGE}FILES+= test_read_format_raw.data.gz.uu
|
||||
${PACKAGE}FILES+= test_read_format_raw.data.uu
|
||||
${PACKAGE}FILES+= test_read_format_tar_concatenated.tar.uu
|
||||
${PACKAGE}FILES+= test_read_format_tar_empty_filename.tar.uu
|
||||
${PACKAGE}FILES+= test_read_format_tar_empty_with_gnulabel.tar.uu
|
||||
${PACKAGE}FILES+= test_read_format_tar_empty_pax.tar.Z.uu
|
||||
${PACKAGE}FILES+= test_read_format_tar_filename_koi8r.tar.Z.uu
|
||||
${PACKAGE}FILES+= test_read_format_ustar_filename_cp866.tar.Z.uu
|
||||
@ -546,6 +565,7 @@ ${PACKAGE}FILES+= test_read_format_zip_comment_stored_2.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_encryption_data.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_encryption_header.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_encryption_partially.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_extra_padding.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_filename_cp866.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_filename_cp932.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_filename_koi8r.zip.uu
|
||||
@ -555,6 +575,8 @@ ${PACKAGE}FILES+= test_read_format_zip_filename_utf8_ru2.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_high_compression.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_jar.jar.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_length_at_end.zip.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_lzma_alone_leak.zipx.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_lzma.zipx.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_lzma.zipx.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_lzma_multi.zipx.uu
|
||||
${PACKAGE}FILES+= test_read_format_zip_mac_metadata.zip.uu
|
||||
|
@ -53,6 +53,7 @@ TESTS_SRCS= \
|
||||
test_option_b.c \
|
||||
test_option_b64encode.c \
|
||||
test_option_exclude.c \
|
||||
test_option_exclude_vcs.c \
|
||||
test_option_fflags.c \
|
||||
test_option_gid_gname.c \
|
||||
test_option_grzip.c \
|
||||
|
Loading…
Reference in New Issue
Block a user