MFV r357783:

Update libarchive to 3.4.2

Relevant vendor changes:
  PR #1289: atomic extraction support (bsdtar -x --safe-writes)
  PR #1308: big endian fix for UTF16 support in LHA reader
  PR #1326: reject RAR5 files that declare invalid header flags
  Issue #987: fix support 7z archive entries with Delta filter
  Issue #1317: fix compression output buffer handling in XAR writer
  Issue #1319: fix uname or gname longer than 32 characters in pax writer
  Issue #1325: fix use after free when archiving hardlinks in ISO9660 or XAR
  Use localtime_r() and gmtime_r() instead of localtime() and gmtime()

X-MFC-With:	r356212,r356365,r356416
MFC after:	1 week
This commit is contained in:
Martin Matuska 2020-02-12 00:16:56 +00:00
commit f976241773
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=357785
132 changed files with 2549 additions and 688 deletions

View File

@ -1,3 +1,11 @@
Feb 11, 2020: libarchive 3.4.2 released
Jan 23, 2020: Important fixes for writing XAR archives
Jan 20, 2020: New tar option: --safe-writes (atomical file extraction)
Jan 03, 2020: Support mbed TLS (PolarSSL) as optional crypto provider
Dec 30, 2019: libarchive 3.4.1 released
Dec 11, 2019: New pax write option "xattrhdr"

View File

@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BSDCAT_H_INCLUDED
#define BSDCAT_H_INCLUDED
#if defined(PLATFORM_CONFIG_H)
/* Use hand-built config.h in environments that need it. */
#include PLATFORM_CONFIG_H
@ -54,3 +57,5 @@ void usage(FILE *stream, int eval);
void bsdcat_next(void);
void bsdcat_print_error(void);
void bsdcat_read_to_stdout(const char* filename);
#endif

View File

@ -59,7 +59,7 @@ DEFINE_TEST(test_0)
* we know some option that will succeed.
*/
if (0 != systemf("%s --version >" DEV_NULL, testprog)) {
failure("Unable to successfully run: %s --version\n", testprog, testprog);
failure("Unable to successfully run: %s --version\n", testprog);
assert(0);
}

View File

@ -1139,6 +1139,14 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
const char *fmt;
time_t mtime;
static time_t now;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (!now)
time(&now);
@ -1186,7 +1194,19 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
else
fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M";
#endif
strftime(date, sizeof(date), fmt, localtime(&mtime));
#if defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&mtime, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = mtime;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&mtime);
#endif
strftime(date, sizeof(date), fmt, ltime);
fprintf(out, "%s%3d %-8s %-8s %8s %12s %s",
archive_entry_strmode(entry),

View File

@ -33,15 +33,15 @@ verify_files(const char *msg)
*/
/* Regular file with 2 links. */
failure(msg);
failure("%s", msg);
assertIsReg("file", 0644);
failure(msg);
failure("%s", msg);
assertFileSize("file", 10);
failure(msg);
failure("%s", msg);
assertFileNLinks("file", 2);
/* Another name for the same file. */
failure(msg);
failure("%s", msg);
assertIsHardlink("linkfile", "file");
/* Symlink */
@ -49,11 +49,11 @@ verify_files(const char *msg)
assertIsSymlink("symlink", "file", 0);
/* Another file with 1 link and different permissions. */
failure(msg);
failure("%s", msg);
assertIsReg("file2", 0777);
failure(msg);
failure("%s", msg);
assertFileSize("file2", 10);
failure(msg);
failure("%s", msg);
assertFileNLinks("file2", 1);
/* dir */

View File

@ -205,9 +205,11 @@ DEFINE_TEST(test_format_newc)
gid = from_hex(e + 30, 8); /* gid */
assertEqualMem(e + 38, "00000003", 8); /* nlink */
t = from_hex(e + 46, 8); /* mtime */
failure("t=0x%08x now=0x%08x=%d", t, now, now);
failure("t=%#08jx now=%#08jx=%jd", (intmax_t)t, (intmax_t)now,
(intmax_t)now);
assert(t <= now); /* File wasn't created in future. */
failure("t=0x%08x now - 2=0x%08x = %d", t, now - 2, now - 2);
failure("t=%#08jx now - 2=%#08jx=%jd", (intmax_t)t, (intmax_t)now - 2,
(intmax_t)now - 2);
assert(t >= now - 2); /* File was created w/in last 2 secs. */
failure("newc format stores body only with last appearance of a link\n"
" first appearance should be empty, so this file size\n"
@ -243,7 +245,8 @@ DEFINE_TEST(test_format_newc)
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
assertEqualMem(e + 38, "00000001", 8); /* nlink */
t2 = from_hex(e + 46, 8); /* mtime */
failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
failure("First entry created at t=%#08jx this entry created"
" at t2=%#08jx", (intmax_t)t, (intmax_t)t2);
assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
assertEqualMem(e + 54, "00000005", 8); /* File size */
fs = from_hex(e + 54, 8);
@ -278,7 +281,8 @@ DEFINE_TEST(test_format_newc)
assertEqualInt(nlinks("dir"), from_hex(e + 38, 8)); /* nlinks */
#endif
t2 = from_hex(e + 46, 8); /* mtime */
failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
failure("First entry created at t=%#08jx this entry created at"
"t2=%#08jx", (intmax_t)t, (intmax_t)t2);
assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
assertEqualMem(e + 54, "00000000", 8); /* File size */
fs = from_hex(e + 54, 8);
@ -311,7 +315,8 @@ DEFINE_TEST(test_format_newc)
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
assertEqualMem(e + 38, "00000003", 8); /* nlink */
t2 = from_hex(e + 46, 8); /* mtime */
failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
failure("First entry created at t=%#08jx this entry created at"
"t2=%#08jx", (intmax_t)t, (intmax_t)t2);
assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
assertEqualInt(10, from_hex(e + 54, 8)); /* File size */
fs = from_hex(e + 54, 8);

View File

@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3004001
#define ARCHIVE_VERSION_NUMBER 3004002
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.4.1"
#define ARCHIVE_VERSION_ONLY_STRING "3.4.2"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@ -693,6 +693,8 @@ __LA_DECL int archive_read_set_passphrase_callback(struct archive *,
#define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000)
/* Default: Do not clear no-change flags when unlinking object */
#define ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS (0x20000)
/* Default: Do not extract atomically (using rename) */
#define ARCHIVE_EXTRACT_SAFE_WRITES (0x40000)
__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
int flags);

View File

@ -25,13 +25,13 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
#include "archive_string.h"
struct archive_acl_entry {

View File

@ -12,8 +12,9 @@
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#ifndef BLAKE2_H
#define BLAKE2_H
#ifndef ARCHIVE_BLAKE2_H
#define ARCHIVE_BLAKE2_H
#include <stddef.h>
#include <stdint.h>

View File

@ -12,8 +12,9 @@
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#ifndef BLAKE2_IMPL_H
#define BLAKE2_IMPL_H
#ifndef ARCHIVE_BLAKE2_IMPL_H
#define ARCHIVE_BLAKE2_IMPL_H
#include <stdint.h>
#include <string.h>

View File

@ -25,15 +25,15 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_CMDLINE_PRIVATE_H
#define ARCHIVE_CMDLINE_PRIVATE_H
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#ifndef ARCHIVE_CMDLINE_PRIVATE_H
#define ARCHIVE_CMDLINE_PRIVATE_H
struct archive_cmdline {
char *path;
char **argv;

View File

@ -25,6 +25,9 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_CRC32_H
#define ARCHIVE_CRC32_H
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
@ -76,3 +79,5 @@ crc32(unsigned long crc, const void *_p, size_t len)
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
return (crc ^ 0xffffffffUL);
}
#endif

View File

@ -23,13 +23,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
/*
* On systems that do not support any recognized crypto libraries,
* the archive_cryptor.c file will normally define no usable symbols.

View File

@ -24,13 +24,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
#define ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
/*
* Crypto support in various Operating Systems:
*

View File

@ -28,16 +28,15 @@
* Borrowed from FreeBSD's <sys/endian.h>
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ENDIAN_H_INCLUDED
#define ARCHIVE_ENDIAN_H_INCLUDED
/* Note: This is a purely internal header! */
/* Do not use this outside of libarchive internal code! */
#ifndef ARCHIVE_ENDIAN_H_INCLUDED
#define ARCHIVE_ENDIAN_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
/*
* Disabling inline keyword for compilers known to choke on it:

View File

@ -1699,7 +1699,7 @@ static const struct flag {
const wchar_t *wname;
unsigned long set;
unsigned long clear;
} flags[] = {
} fileflags[] = {
/* Preferred (shorter) names per flag first, all prefixed by "no" */
#ifdef SF_APPEND
{ "nosappnd", L"nosappnd", SF_APPEND, 0},
@ -1876,7 +1876,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
bits = bitset | bitclear;
length = 0;
for (flag = flags; flag->name != NULL; flag++)
for (flag = fileflags; flag->name != NULL; flag++)
if (bits & (flag->set | flag->clear)) {
length += strlen(flag->name) + 1;
bits &= ~(flag->set | flag->clear);
@ -1889,7 +1889,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
return (NULL);
dp = string;
for (flag = flags; flag->name != NULL; flag++) {
for (flag = fileflags; flag->name != NULL; flag++) {
if (bitset & flag->set || bitclear & flag->clear) {
sp = flag->name + 2;
} else if (bitset & flag->clear || bitclear & flag->set) {
@ -1941,7 +1941,7 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
*end != ' ' && *end != ',')
end++;
length = end - start;
for (flag = flags; flag->name != NULL; flag++) {
for (flag = fileflags; flag->name != NULL; flag++) {
size_t flag_length = strlen(flag->name);
if (length == flag_length
&& memcmp(start, flag->name, length) == 0) {
@ -2009,7 +2009,7 @@ ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
*end != L' ' && *end != L',')
end++;
length = end - start;
for (flag = flags; flag->wname != NULL; flag++) {
for (flag = fileflags; flag->wname != NULL; flag++) {
size_t flag_length = wcslen(flag->wname);
if (length == flag_length
&& wmemcmp(start, flag->wname, length) == 0) {

View File

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

View File

@ -25,13 +25,13 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
struct archive_entry;
struct archive_string_conv;

View File

@ -25,13 +25,13 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#include "archive_acl_private.h"
#include "archive_string.h"

View File

@ -27,6 +27,7 @@
** This code is in the public domain and has no copyright.
*/
#include "archive_platform.h"
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -694,8 +695,16 @@ Convert(time_t Month, time_t Day, time_t Year,
signed char DaysInMonth[12] = {
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
time_t Julian;
int i;
time_t Julian;
int i;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (Year < 69)
Year += 2000;
@ -722,21 +731,64 @@ Convert(time_t Month, time_t Day, time_t Year,
Julian *= DAY;
Julian += Timezone;
Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
#if defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Julian, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Julian;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Julian);
#endif
if (DSTmode == DSTon
|| (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
|| (DSTmode == DSTmaybe && ltime->tm_isdst))
Julian -= HOUR;
return Julian;
}
static time_t
DSTcorrect(time_t Start, time_t Future)
{
time_t StartDay;
time_t FutureDay;
time_t StartDay;
time_t FutureDay;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
StartDay = (localtime(&Start)->tm_hour + 1) % 24;
FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
#if defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Start, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Start;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Start);
#endif
StartDay = (ltime->tm_hour + 1) % 24;
#if defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Future, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Future;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Future);
#endif
FutureDay = (ltime->tm_hour + 1) % 24;
return (Future - Start) + (StartDay - FutureDay) * HOUR;
}
@ -747,9 +799,27 @@ RelativeDate(time_t Start, time_t zone, int dstmode,
{
struct tm *tm;
time_t t, now;
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
struct tm tmbuf;
#endif
#if defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
t = Start - zone;
#if defined(HAVE_GMTIME_R)
tm = gmtime_r(&t, &tmbuf);
#elif defined(HAVE__GMTIME64_S)
tmptime = t;
terr = _gmtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = gmtime(&t);
#endif
now = Start;
now += DAY * ((DayNumber - tm->tm_wday + 7) % 7);
now += 7 * DAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
@ -765,10 +835,28 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
struct tm *tm;
time_t Month;
time_t Year;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (RelMonth == 0)
return 0;
#if defined(HAVE_LOCALTIME_R)
tm = localtime_r(&Start, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Start;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&Start);
#endif
Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
Year = Month / 12;
Month = Month % 12 + 1;
@ -905,6 +993,10 @@ __archive_get_date(time_t now, const char *p)
time_t Start;
time_t tod;
long tzone;
#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/* Clear out the parsed token array. */
memset(tokens, 0, sizeof(tokens));
@ -913,20 +1005,44 @@ __archive_get_date(time_t now, const char *p)
gds = &_gds;
/* Look up the current time. */
#if defined(HAVE_LOCALTIME_R)
tm = localtime_r(&now, &local);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = now;
terr = _localtime64_s(&local, &tmptime);
if (terr)
tm = NULL;
else
tm = &local;
#else
memset(&local, 0, sizeof(local));
tm = localtime (&now);
tm = localtime(&now);
#endif
if (tm == NULL)
return -1;
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
local = *tm;
#endif
/* Look up UTC if we can and use that to determine the current
* timezone offset. */
#if defined(HAVE_GMTIME_R)
gmt_ptr = gmtime_r(&now, &gmt);
#elif defined(HAVE__GMTIME64_S)
tmptime = now;
terr = _gmtime64_s(&gmt, &tmptime);
if (terr)
gmt_ptr = NULL;
else
gmt_ptr = &gmt;
#else
memset(&gmt, 0, sizeof(gmt));
gmt_ptr = gmtime (&now);
gmt_ptr = gmtime(&now);
if (gmt_ptr != NULL) {
/* Copy, in case localtime and gmtime use the same buffer. */
gmt = *gmt_ptr;
}
#endif
if (gmt_ptr != NULL)
tzone = difftm (&gmt, &local);
else
@ -960,7 +1076,18 @@ __archive_get_date(time_t now, const char *p)
* time components instead of the local timezone. */
if (gds->HaveZone && gmt_ptr != NULL) {
now -= gds->Timezone;
gmt_ptr = gmtime (&now);
#if defined(HAVE_GMTIME_R)
gmt_ptr = gmtime_r(&now, &gmt);
#elif defined(HAVE__GMTIME64_S)
tmptime = now;
terr = _gmtime64_s(&gmt, &tmptime);
if (terr)
gmt_ptr = NULL;
else
gmt_ptr = &gmt;
#else
gmt_ptr = gmtime(&now);
#endif
if (gmt_ptr != NULL)
local = *gmt_ptr;
now += gds->Timezone;

View File

@ -25,13 +25,13 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_GETDATE_H_INCLUDED
#define ARCHIVE_GETDATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_GETDATE_H_INCLUDED
#define ARCHIVE_GETDATE_H_INCLUDED
#include <time.h>
time_t __archive_get_date(time_t now, const char *);

View File

@ -23,13 +23,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
/*
* On systems that do not support any recognized crypto libraries,
* the archive_hmac.c file is expected to define no usable symbols.

View File

@ -22,9 +22,14 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
#define ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#include <openssl/evp.h>
#include <openssl/opensslv.h>

View File

@ -22,9 +22,14 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
#define ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#include <openssl/hmac.h>
#include <openssl/opensslv.h>

View File

@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
#define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
@ -45,3 +48,4 @@ _archive_set_either_option(struct archive *a,
const char *m, const char *o, const char *v,
option_handler use_format_option, option_handler use_filter_option);
#endif

View File

@ -57,11 +57,12 @@ __RCSID("$NetBSD$");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#ifdef HAVE_SYS_MKDEV_H
#if MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#define HAVE_MAJOR
#elif MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#define HAVE_MAJOR
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>

View File

@ -31,8 +31,8 @@
/* Originally from NetBSD's mknod(8) source. */
#ifndef _PACK_DEV_H
#define _PACK_DEV_H
#ifndef ARCHIVE_PACK_DEV_H
#define ARCHIVE_PACK_DEV_H
typedef dev_t pack_t(int, unsigned long [], const char **);
@ -46,4 +46,4 @@ pack_t pack_native;
(((y) << 12) & 0xfff00000) | \
(((y) << 0) & 0x000000ff)))
#endif /* _PACK_DEV_H */
#endif /* ARCHIVE_PACK_DEV_H */

View File

@ -26,15 +26,15 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_PATHMATCH_H
#define ARCHIVE_PATHMATCH_H
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#ifndef ARCHIVE_PATHMATCH_H
#define ARCHIVE_PATHMATCH_H
/* Don't anchor at beginning unless the pattern starts with "^" */
#define PATHMATCH_NO_ANCHOR_START 1
/* Don't anchor at end unless the pattern ends with "$" */

View File

@ -30,6 +30,12 @@
#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
#define ARCHIVE_PLATFORM_ACL_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST_COMMON
#error This header is only to be used internally to libarchive.
#endif
#endif
/*
* Determine what ACL types are supported
*/

View File

@ -30,6 +30,12 @@
#ifndef ARCHIVE_PLATFORM_XATTR_H_INCLUDED
#define ARCHIVE_PLATFORM_XATTR_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST_COMMON
#error This header is only to be used internally to libarchive.
#endif
#endif
/*
* Determine if we support extended attributes
*/

View File

@ -1000,7 +1000,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
{
p->Low += start * (p->Range /= total);
p->Low += (UInt64)start * (UInt64)(p->Range /= total);
p->Range *= size;
while (p->Range < kTopValue)
{

View File

@ -6,13 +6,13 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
#include "archive_ppmd_private.h"
#define PPMD7_MIN_ORDER 2

View File

@ -4,8 +4,8 @@ This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
#ifndef __PPMD8_H
#define __PPMD8_H
#ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
#include "archive_ppmd_private.h"

View File

@ -2,13 +2,13 @@
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
#include <stddef.h>
#include "archive_read_private.h"

View File

@ -25,13 +25,13 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
#define ARCHIVE_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
#define ARCHIVE_PRIVATE_H_INCLUDED
#if HAVE_ICONV_H
#include <iconv.h>
#endif
@ -153,6 +153,11 @@ void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
void __archive_ensure_cloexec_flag(int fd);
int __archive_mktemp(const char *tmpdir);
#if defined(_WIN32) && !defined(__CYGWIN__)
int __archive_mkstemp(wchar_t *template);
#else
int __archive_mkstemp(char *template);
#endif
int __archive_clean(struct archive *);

View File

@ -23,13 +23,13 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
/* Random number generator. */
int archive_random(void *buf, size_t nbytes);

View File

@ -28,8 +28,9 @@
*
* Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
*/
#ifndef ARCHIVE_RB_H_
#define ARCHIVE_RB_H_
#ifndef ARCHIVE_RB_H_INCLUDED
#define ARCHIVE_RB_H_INCLUDED
struct archive_rb_node {
struct archive_rb_node *rb_nodes[2];
@ -48,12 +49,24 @@ struct archive_rb_node {
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
#define ARCHIVE_RB_TREE_MAX(T) \
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
#define ARCHIVE_RB_TREE_NEXT(T, N) \
__archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT)
#define ARCHIVE_RB_TREE_PREV(T, N) \
__archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT)
#define ARCHIVE_RB_TREE_FOREACH(N, T) \
for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT))
(N) = ARCHIVE_RB_TREE_NEXT((T), (N)))
#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT))
(N) = ARCHIVE_RB_TREE_PREV((T), (N)))
#define ARCHIVE_RB_TREE_FOREACH_SAFE(N, T, S) \
for ((N) = ARCHIVE_RB_TREE_MIN(T); \
(N) && ((S) = ARCHIVE_RB_TREE_NEXT((T), (N)), 1); \
(N) = (S))
#define ARCHIVE_RB_TREE_FOREACH_REVERSE_SAFE(N, T, S) \
for ((N) = ARCHIVE_RB_TREE_MAX(T); \
(N) && ((S) = ARCHIVE_RB_TREE_PREV((T), (N)), 1); \
(N) = (S))
/*
* archive_rbto_compare_nodes_fn:

View File

@ -433,7 +433,7 @@ archive_read_add_callback_data(struct archive *_a, void *client_data,
return ARCHIVE_FATAL;
}
a->client.dataset = (struct archive_read_data_node *)p;
for (i = a->client.nodes - 1; i > iindex && i > 0; i--) {
for (i = a->client.nodes - 1; i > iindex; i--) {
a->client.dataset[i].data = a->client.dataset[i-1].data;
a->client.dataset[i].begin_position = -1;
a->client.dataset[i].total_size = -1;

View File

@ -729,27 +729,23 @@ _archive_read_data_block(struct archive *_a, const void **buff,
if ((t->flags & needsRestoreTimes) != 0 &&
t->restore_time.noatime == 0)
flags |= O_NOATIME;
do {
#endif
t->entry_fd = open_on_current_dir(t,
tree_current_access_path(t), flags);
__archive_ensure_cloexec_flag(t->entry_fd);
t->entry_fd = open_on_current_dir(t,
tree_current_access_path(t), flags);
__archive_ensure_cloexec_flag(t->entry_fd);
#if defined(O_NOATIME)
/*
* When we did open the file with O_NOATIME flag,
* if successful, set 1 to t->restore_time.noatime
* not to restore an atime of the file later.
* if failed by EPERM, retry it without O_NOATIME flag.
*/
if (flags & O_NOATIME) {
if (t->entry_fd >= 0)
t->restore_time.noatime = 1;
else if (errno == EPERM) {
flags &= ~O_NOATIME;
continue;
}
}
} while (0);
/*
* When we did open the file with O_NOATIME flag,
* if successful, set 1 to t->restore_time.noatime
* not to restore an atime of the file later.
* if failed by EPERM, retry it without O_NOATIME flag.
*/
if (flags & O_NOATIME) {
if (t->entry_fd >= 0)
t->restore_time.noatime = 1;
else if (errno == EPERM)
flags &= ~O_NOATIME;
}
#endif
if (t->entry_fd < 0) {
archive_set_error(&a->archive, errno,
@ -1110,8 +1106,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
"%s", delayed_str.s);
}
}
if (!archive_string_empty(&delayed_str))
archive_string_free(&delayed_str);
archive_string_free(&delayed_str);
return (r);
}

View File

@ -26,13 +26,13 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
#include "archive_platform_acl.h"
struct tree;

View File

@ -25,15 +25,15 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_PRIVATE_H_INCLUDED
#include "archive.h"
#include "archive_string.h"
#include "archive_private.h"

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 2, 2012
.Dd January 31, 2020
.Dt ARCHIVE_READ_OPTIONS 3
.Os
.Sh NAME
@ -180,6 +180,18 @@ only to modules whose name matches
.\"
.Sh OPTIONS
.Bl -tag -compact -width indent
.It Format cab
.Bl -tag -compact -width indent
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file names.
.El
.It Format cpio
.Bl -tag -compact -width indent
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file names.
.El
.It Format iso9660
.Bl -tag -compact -width indent
.It Cm joliet
@ -193,6 +205,24 @@ Defaults to enabled, use
.Cm !rockridge
to disable.
.El
.It Format lha
.Bl -tag -compact -width indent
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file names.
.El
.It Format mtree
.Bl -tag -compact -width indent
.It Cm checkfs
Allow reading information missing from the mtree from the file system.
Disabled by default.
.El
.It Format rar
.Bl -tag -compact -width indent
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file names.
.El
.It Format tar
.Bl -tag -compact -width indent
.It Cm compat-2x
@ -202,7 +232,7 @@ This option mimics the libarchive 2.x filename handling
so that such archives can be read correctly.
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating filenames.
used when translating file names.
.It Cm mac-ext
Support Mac OS metadata extension that records data in special
files beginning with a period and underscore.

View File

@ -574,14 +574,13 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
while (l > 0) {
int n = 0;
if (l > 0) {
if (!uuchar[b[0]] || !uuchar[b[1]])
break;
n = UUDECODE(*b++) << 18;
n |= UUDECODE(*b++) << 12;
*out++ = n >> 16; total++;
--l;
}
if (!uuchar[b[0]] || !uuchar[b[1]])
break;
n = UUDECODE(*b++) << 18;
n |= UUDECODE(*b++) << 12;
*out++ = n >> 16; total++;
--l;
if (l > 0) {
if (!uuchar[b[0]])
break;
@ -626,14 +625,13 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
while (l > 0) {
int n = 0;
if (l > 0) {
if (!base64[b[0]] || !base64[b[1]])
break;
n = base64num[*b++] << 18;
n |= base64num[*b++] << 12;
*out++ = n >> 16; total++;
l -= 2;
}
if (!base64[b[0]] || !base64[b[1]])
break;
n = base64num[*b++] << 18;
n |= base64num[*b++] << 12;
*out++ = n >> 16; total++;
l -= 2;
if (l > 0) {
if (*b == '=')
break;

View File

@ -1086,10 +1086,17 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
zip->bcj_state = 0;
break;
case _7Z_DELTA:
if (coder2->propertiesSize != 1) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Delta parameter");
return (ARCHIVE_FAILED);
}
filters[fi].id = LZMA_FILTER_DELTA;
memset(&delta_opt, 0, sizeof(delta_opt));
delta_opt.type = LZMA_DELTA_TYPE_BYTE;
delta_opt.dist = 1;
delta_opt.dist =
(uint32_t)coder2->properties[0] + 1;
filters[fi].options = &delta_opt;
fi++;
break;

View File

@ -1246,8 +1246,9 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
archive_array_append(&lha->filename,
(const char *)extdheader, datasize);
/* Setup a string conversion for a filename. */
lha->sconv_fname = archive_string_conversion_from_charset(
&a->archive, "UTF-16LE", 1);
lha->sconv_fname =
archive_string_conversion_from_charset(&a->archive,
"UTF-16LE", 1);
if (lha->sconv_fname == NULL)
return (ARCHIVE_FATAL);
break;
@ -1273,32 +1274,46 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
break;
case EXT_UTF16_DIRECTORY:
/* UTF-16 characters take always 2 or 4 bytes */
if (datasize == 0 || (datasize & 1) || extdheader[0] == '\0')
if (datasize == 0 || (datasize & 1) ||
extdheader[0] == '\0') {
/* no directory name data. exit this case. */
goto invalid;
}
archive_string_empty(&lha->dirname);
archive_array_append(&lha->dirname,
(const char *)extdheader, datasize);
lha->sconv_dir = archive_string_conversion_from_charset(
&a->archive, "UTF-16LE", 1);
lha->sconv_dir =
archive_string_conversion_from_charset(&a->archive,
"UTF-16LE", 1);
if (lha->sconv_dir == NULL)
return (ARCHIVE_FATAL);
else {
/*
* Convert directory delimiter from 0xFF
* Convert directory delimiter from 0xFFFF
* to '/' for local system.
*/
uint16_t dirSep;
uint16_t d = 1;
if (archive_be16dec(&d) == 1)
dirSep = 0x2F00;
else
dirSep = 0x002F;
/* UTF-16LE character */
uint16_t *utf16name = (uint16_t *)lha->dirname.s;
uint16_t *utf16name =
(uint16_t *)lha->dirname.s;
for (i = 0; i < lha->dirname.length / 2; i++) {
if (utf16name[i] == 0xFFFF)
utf16name[i] = L'/';
if (utf16name[i] == 0xFFFF) {
utf16name[i] = dirSep;
}
}
/* Is last character directory separator? */
if (utf16name[lha->dirname.length / 2 - 1] != L'/')
if (utf16name[lha->dirname.length / 2 - 1] !=
dirSep) {
/* invalid directory data */
goto invalid;
}
}
break;
case EXT_DOS_ATTR:

View File

@ -258,6 +258,7 @@ archive_read_support_format_mtree(struct archive *_a)
"Can't allocate mtree data");
return (ARCHIVE_FATAL);
}
mtree->checkfs = 0;
mtree->fd = -1;
__archive_rb_tree_init(&mtree->rbtree, &rb_ops);

View File

@ -148,6 +148,9 @@
#define FILE_ATTRIBUTE_DIRECTORY 0x10
#endif
#undef minimum
#define minimum(a, b) ((a)<(b)?(a):(b))
/* Fields common to all headers */
struct rar_header
{
@ -1722,6 +1725,13 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
struct tm *tm;
time_t t;
long nsec;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (p + 2 > endp)
return (-1);
@ -1753,7 +1763,18 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
p++;
}
#if defined(HAVE_LOCALTIME_R)
tm = localtime_r(&t, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = t;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&t);
#endif
nsec = tm->tm_sec + rem / NS_UNIT;
if (rmode & 4)
{
@ -2452,8 +2473,11 @@ create_code(struct archive_read *a, struct huffman_code *code,
if (add_value(a, code, j, codebits, i) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
codebits++;
if (--symbolsleft <= 0) { break; break; }
if (--symbolsleft <= 0)
break;
}
if (symbolsleft <= 0)
break;
codebits <<= 1;
}
return (ARCHIVE_OK);
@ -2463,7 +2487,8 @@ static int
add_value(struct archive_read *a, struct huffman_code *code, int value,
int codebits, int length)
{
int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode;
int lastnode, bitpos, bit;
/* int repeatpos, repeatnode, nextnode; */
free(code->table);
code->table = NULL;
@ -2473,6 +2498,9 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
if(length < code->minlength)
code->minlength = length;
/*
* Dead code, repeatpos was is -1
*
repeatpos = -1;
if (repeatpos == 0 || (repeatpos >= 0
&& (((codebits >> (repeatpos - 1)) & 3) == 0
@ -2482,6 +2510,7 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
"Invalid repeat position");
return (ARCHIVE_FATAL);
}
*/
lastnode = 0;
for (bitpos = length - 1; bitpos >= 0; bitpos--)
@ -2497,9 +2526,12 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
return (ARCHIVE_FATAL);
}
/*
* Dead code, repeatpos was -1, bitpos >=0
*
if (bitpos == repeatpos)
{
/* Open branch check */
* Open branch check *
if (!(code->tree[lastnode].branches[bit] < 0))
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@ -2518,16 +2550,17 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
return (ARCHIVE_FATAL);
}
/* Set branches */
* Set branches *
code->tree[lastnode].branches[bit] = repeatnode;
code->tree[repeatnode].branches[bit] = repeatnode;
code->tree[repeatnode].branches[bit^1] = nextnode;
lastnode = nextnode;
bitpos++; /* terminating bit already handled, skip it */
bitpos++; * terminating bit already handled, skip it *
}
else
{
*/
/* Open branch check */
if (code->tree[lastnode].branches[bit] < 0)
{
@ -2541,7 +2574,7 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
/* set to branch */
lastnode = code->tree[lastnode].branches[bit];
}
/* } */
}
if (!(code->tree[lastnode].branches[0] == -1
@ -2625,11 +2658,15 @@ make_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
table[i].value = code->tree[node].branches[0];
}
}
/*
* Dead code, node >= 0
*
else if (node < 0)
{
for(i = 0; i < currtablesize; i++)
table[i].length = -1;
}
*/
else
{
if(depth == maxdepth)
@ -2661,6 +2698,10 @@ expand(struct archive_read *a, int64_t end)
0, 1, 1, 1, 1, 2, 2,
2, 2, 3, 3, 3, 3, 4,
4, 4, 4, 5, 5, 5, 5 };
static const int lengthb_min = minimum(
(int)(sizeof(lengthbases)/sizeof(lengthbases[0])),
(int)(sizeof(lengthbits)/sizeof(lengthbits[0]))
);
static const unsigned int offsetbases[] =
{ 0, 1, 2, 3, 4, 6,
8, 12, 16, 24, 32, 48,
@ -2678,6 +2719,10 @@ expand(struct archive_read *a, int64_t end)
11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
static const int offsetb_min = minimum(
(int)(sizeof(offsetbases)/sizeof(offsetbases[0])),
(int)(sizeof(offsetbits)/sizeof(offsetbits[0]))
);
static const unsigned char shortbases[] =
{ 0, 4, 8, 16, 32, 64, 128, 192 };
static const unsigned char shortbits[] =
@ -2757,9 +2802,7 @@ expand(struct archive_read *a, int64_t end)
if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
goto bad_data;
if (lensymbol > (int)(sizeof(lengthbases)/sizeof(lengthbases[0])))
goto bad_data;
if (lensymbol > (int)(sizeof(lengthbits)/sizeof(lengthbits[0])))
if (lensymbol > lengthb_min)
goto bad_data;
len = lengthbases[lensymbol] + 2;
if (lengthbits[lensymbol] > 0) {
@ -2791,9 +2834,7 @@ expand(struct archive_read *a, int64_t end)
}
else
{
if (symbol-271 > (int)(sizeof(lengthbases)/sizeof(lengthbases[0])))
goto bad_data;
if (symbol-271 > (int)(sizeof(lengthbits)/sizeof(lengthbits[0])))
if (symbol-271 > lengthb_min)
goto bad_data;
len = lengthbases[symbol-271]+3;
if(lengthbits[symbol-271] > 0) {
@ -2805,9 +2846,7 @@ expand(struct archive_read *a, int64_t end)
if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
goto bad_data;
if (offssymbol > (int)(sizeof(offsetbases)/sizeof(offsetbases[0])))
goto bad_data;
if (offssymbol > (int)(sizeof(offsetbits)/sizeof(offsetbits[0])))
if (offssymbol > offsetb_min)
goto bad_data;
offs = offsetbases[offssymbol]+1;
if(offsetbits[offssymbol] > 0)

View File

@ -73,15 +73,14 @@
* 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00
* "Rar!→•☺·\x00"
*
* It's stored in `rar5_signature` after XOR'ing it with 0xA1, because I don't
* Retrieved with `rar5_signature()` by XOR'ing it with 0xA1, because I don't
* want to put this magic sequence in each binary that uses libarchive, so
* applications that scan through the file for this marker won't trigger on
* this "false" one.
*
* The array itself is decrypted in `rar5_init` function. */
static unsigned char rar5_signature[] = { 243, 192, 211, 128, 187, 166, 160, 161 };
static const ssize_t rar5_signature_size = sizeof(rar5_signature);
static unsigned char rar5_signature_xor[] = { 243, 192, 211, 128, 187, 166, 160, 161 };
static const size_t g_unpack_window_size = 0x20000;
/* These could have been static const's, but they aren't, because of
@ -211,7 +210,7 @@ struct comp_state {
or just a part of it. */
uint8_t block_parsing_finished : 1;
int notused : 4;
signed int notused : 4;
int flags; /* Uncompression flags. */
int method; /* Uncompression algorithm method. */
@ -357,6 +356,7 @@ struct rar5 {
/* Forward function declarations. */
static void rar5_signature(char *buf);
static int verify_global_checksums(struct archive_read* a);
static int rar5_read_data_skip(struct archive_read *a);
static int push_data_ready(struct archive_read* a, struct rar5* rar,
@ -384,7 +384,7 @@ static int cdeque_init(struct cdeque* d, int max_capacity_power_of_2) {
d->cap_mask = max_capacity_power_of_2 - 1;
d->arr = NULL;
if((max_capacity_power_of_2 & d->cap_mask) > 0)
if((max_capacity_power_of_2 & d->cap_mask) != 0)
return CDE_PARAM;
cdeque_clear(d);
@ -881,10 +881,10 @@ static inline int get_archive_read(struct archive* a,
static int read_ahead(struct archive_read* a, size_t how_many,
const uint8_t** ptr)
{
ssize_t avail = -1;
if(!ptr)
return 0;
ssize_t avail = -1;
*ptr = __archive_read_ahead(a, how_many, &avail);
if(*ptr == NULL) {
return 0;
@ -1086,11 +1086,14 @@ static int read_u64(struct archive_read* a, uint64_t* pvalue) {
static int bid_standard(struct archive_read* a) {
const uint8_t* p;
char signature[sizeof(rar5_signature_xor)];
if(!read_ahead(a, rar5_signature_size, &p))
rar5_signature(signature);
if(!read_ahead(a, sizeof(rar5_signature_xor), &p))
return -1;
if(!memcmp(rar5_signature, p, rar5_signature_size))
if(!memcmp(signature, p, sizeof(rar5_signature_xor)))
return 30;
return -1;
@ -1150,14 +1153,14 @@ static int process_main_locator_extra_block(struct archive_read* a,
{
uint64_t locator_flags;
if(!read_var(a, &locator_flags, NULL)) {
return ARCHIVE_EOF;
}
enum LOCATOR_FLAGS {
QLIST = 0x01, RECOVERY = 0x02,
};
if(!read_var(a, &locator_flags, NULL)) {
return ARCHIVE_EOF;
}
if(locator_flags & QLIST) {
if(!read_var(a, &rar->qlist_offset, NULL)) {
return ARCHIVE_EOF;
@ -1183,6 +1186,10 @@ static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
size_t hash_type = 0;
size_t value_len;
enum HASH_TYPE {
BLAKE2sp = 0x00
};
if(!read_var_sized(a, &hash_type, &value_len))
return ARCHIVE_EOF;
@ -1191,10 +1198,6 @@ static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
return ARCHIVE_EOF;
}
enum HASH_TYPE {
BLAKE2sp = 0x00
};
/* The file uses BLAKE2sp checksum algorithm instead of plain old
* CRC32. */
if(hash_type == BLAKE2sp) {
@ -1257,6 +1260,7 @@ static int parse_file_extra_version(struct archive_read* a,
size_t value_len = 0;
struct archive_string version_string;
struct archive_string name_utf8_string;
const char* cur_filename;
/* Flags are ignored. */
if(!read_var_sized(a, &flags, &value_len))
@ -1275,7 +1279,7 @@ static int parse_file_extra_version(struct archive_read* a,
/* extra_data_size should be zero here. */
const char* cur_filename = archive_entry_pathname_utf8(e);
cur_filename = archive_entry_pathname_utf8(e);
if(cur_filename == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Version entry without file name");
@ -1586,6 +1590,25 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
char name_utf8_buf[MAX_NAME_IN_BYTES];
const uint8_t* p;
enum FILE_FLAGS {
DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004,
UNKNOWN_UNPACKED_SIZE = 0x0008,
};
enum FILE_ATTRS {
ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4,
ATTR_DIRECTORY = 0x10,
};
enum COMP_INFO_FLAGS {
SOLID = 0x0040,
};
enum HOST_OS {
HOST_WINDOWS = 0,
HOST_UNIX = 1,
};
archive_entry_clear(entry);
/* Do not reset file context if we're switching archives. */
@ -1615,20 +1638,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
return ARCHIVE_FATAL;
}
enum FILE_FLAGS {
DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004,
UNKNOWN_UNPACKED_SIZE = 0x0008,
};
enum FILE_ATTRS {
ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4,
ATTR_DIRECTORY = 0x10,
};
enum COMP_INFO_FLAGS {
SOLID = 0x0040,
};
if(!read_var_sized(a, &file_flags, NULL))
return ARCHIVE_EOF;
@ -1725,11 +1734,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
if(!read_var_sized(a, &host_os, NULL))
return ARCHIVE_EOF;
enum HOST_OS {
HOST_WINDOWS = 0,
HOST_UNIX = 1,
};
if(host_os == HOST_WINDOWS) {
/* Host OS is Windows */
@ -1821,12 +1825,16 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
int ret = process_head_file_extra(a, entry, rar,
extra_data_size);
/* Sanity check. */
/*
* TODO: rewrite or remove useless sanity check
* as extra_data_size is not passed as a pointer
*
if(extra_data_size < 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"File extra data size is not zero");
return ARCHIVE_FATAL;
}
*/
if(ret != ARCHIVE_OK)
return ret;
@ -1891,14 +1899,28 @@ static int process_head_service(struct archive_read* a, struct rar5* rar,
static int process_head_main(struct archive_read* a, struct rar5* rar,
struct archive_entry* entry, size_t block_flags)
{
(void) entry;
int ret;
size_t extra_data_size = 0;
size_t extra_field_size = 0;
size_t extra_field_id = 0;
size_t archive_flags = 0;
enum MAIN_FLAGS {
VOLUME = 0x0001, /* multi-volume archive */
VOLUME_NUMBER = 0x0002, /* volume number, first vol doesn't
* have it */
SOLID = 0x0004, /* solid archive */
PROTECT = 0x0008, /* contains Recovery info */
LOCK = 0x0010, /* readonly flag, not used */
};
enum MAIN_EXTRA {
// Just one attribute here.
LOCATOR = 0x01,
};
(void) entry;
if(block_flags & HFL_EXTRA_DATA) {
if(!read_var_sized(a, &extra_data_size, NULL))
return ARCHIVE_EOF;
@ -1910,15 +1932,6 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
return ARCHIVE_EOF;
}
enum MAIN_FLAGS {
VOLUME = 0x0001, /* multi-volume archive */
VOLUME_NUMBER = 0x0002, /* volume number, first vol doesn't
* have it */
SOLID = 0x0004, /* solid archive */
PROTECT = 0x0008, /* contains Recovery info */
LOCK = 0x0010, /* readonly flag, not used */
};
rar->main.volume = (archive_flags & VOLUME) > 0;
rar->main.solid = (archive_flags & SOLID) > 0;
@ -1970,11 +1983,6 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
return ARCHIVE_FATAL;
}
enum MAIN_EXTRA {
// Just one attribute here.
LOCATOR = 0x01,
};
switch(extra_field_id) {
case LOCATOR:
ret = process_main_locator_extra_block(a, rar);
@ -2080,6 +2088,8 @@ static int scan_for_signature(struct archive_read* a);
static int process_base_block(struct archive_read* a,
struct archive_entry* entry)
{
const size_t SMALLEST_RAR5_BLOCK_SIZE = 3;
struct rar5* rar = get_context(a);
uint32_t hdr_crc, computed_crc;
size_t raw_hdr_size = 0, hdr_size_len, hdr_size;
@ -2088,6 +2098,12 @@ static int process_base_block(struct archive_read* a,
const uint8_t* p;
int ret;
enum HEADER_TYPE {
HEAD_MARK = 0x00, HEAD_MAIN = 0x01, HEAD_FILE = 0x02,
HEAD_SERVICE = 0x03, HEAD_CRYPT = 0x04, HEAD_ENDARC = 0x05,
HEAD_UNKNOWN = 0xff,
};
/* Skip any unprocessed data for this file. */
ret = skip_unprocessed_bytes(a);
if(ret != ARCHIVE_OK)
@ -2103,15 +2119,26 @@ static int process_base_block(struct archive_read* a,
return ARCHIVE_EOF;
}
hdr_size = raw_hdr_size + hdr_size_len;
/* Sanity check, maximum header size for RAR5 is 2MB. */
if(raw_hdr_size > (2 * 1024 * 1024)) {
if(hdr_size > (2 * 1024 * 1024)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Base block header is too large");
return ARCHIVE_FATAL;
}
hdr_size = raw_hdr_size + hdr_size_len;
/* Additional sanity checks to weed out invalid files. */
if(raw_hdr_size == 0 || hdr_size_len == 0 ||
hdr_size < SMALLEST_RAR5_BLOCK_SIZE)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Too small block encountered (%zu bytes)",
raw_hdr_size);
return ARCHIVE_FATAL;
}
/* Read the whole header data into memory, maximum memory use here is
* 2MB. */
@ -2146,12 +2173,6 @@ static int process_base_block(struct archive_read* a,
rar->main.endarc = 0;
/* Those are possible header ids in RARv5. */
enum HEADER_TYPE {
HEAD_MARK = 0x00, HEAD_MAIN = 0x01, HEAD_FILE = 0x02,
HEAD_SERVICE = 0x03, HEAD_CRYPT = 0x04, HEAD_ENDARC = 0x05,
HEAD_UNKNOWN = 0xff,
};
switch(header_id) {
case HEAD_MAIN:
ret = process_head_main(a, rar, entry, header_flags);
@ -2264,7 +2285,7 @@ static int rar5_read_header(struct archive_read *a,
}
if(rar->skipped_magic == 0) {
if(ARCHIVE_OK != consume(a, rar5_signature_size)) {
if(ARCHIVE_OK != consume(a, sizeof(rar5_signature_xor))) {
return ARCHIVE_EOF;
}
@ -2536,12 +2557,10 @@ static int parse_tables(struct archive_read* a, struct rar5* rar,
/* 0..15: store directly */
table[i] = (uint8_t) num;
i++;
continue;
}
if(num < 18) {
} else if(num < 18) {
/* 16..17: repeat previous code */
uint16_t n;
if(ARCHIVE_OK != read_bits_16(rar, p, &n))
return ARCHIVE_EOF;
@ -2567,27 +2586,26 @@ static int parse_tables(struct archive_read* a, struct rar5* rar,
"huffman tables");
return ARCHIVE_FATAL;
}
continue;
}
/* other codes: fill with zeroes `n` times */
uint16_t n;
if(ARCHIVE_OK != read_bits_16(rar, p, &n))
return ARCHIVE_EOF;
if(num == 18) {
n >>= 13;
n += 3;
skip_bits(rar, 3);
} else {
n >>= 9;
n += 11;
skip_bits(rar, 7);
}
/* other codes: fill with zeroes `n` times */
uint16_t n;
while(n-- > 0 && i < HUFF_TABLE_SIZE)
table[i++] = 0;
if(ARCHIVE_OK != read_bits_16(rar, p, &n))
return ARCHIVE_EOF;
if(num == 18) {
n >>= 13;
n += 3;
skip_bits(rar, 3);
} else {
n >>= 9;
n += 11;
skip_bits(rar, 7);
}
while(n-- > 0 && i < HUFF_TABLE_SIZE)
table[i++] = 0;
}
}
ret = create_decode_tables(&table[idx], &rar->cstate.ld, HUFF_NC);
@ -2632,6 +2650,7 @@ static int parse_tables(struct archive_read* a, struct rar5* rar,
static int parse_block_header(struct archive_read* a, const uint8_t* p,
ssize_t* block_size, struct compressed_block_header* hdr)
{
uint8_t calculated_cksum;
memcpy(hdr, p, sizeof(struct compressed_block_header));
if(bf_byte_count(hdr) > 2) {
@ -2670,7 +2689,7 @@ static int parse_block_header(struct archive_read* a, const uint8_t* p,
/* Verify the block header checksum. 0x5A is a magic value and is
* always * constant. */
uint8_t calculated_cksum = 0x5A
calculated_cksum = 0x5A
^ (uint8_t) hdr->block_flags_u8
^ (uint8_t) *block_size
^ (uint8_t) (*block_size >> 8)
@ -2744,6 +2763,7 @@ static int is_valid_filter_block_start(struct rar5* rar,
static int parse_filter(struct archive_read* ar, const uint8_t* p) {
uint32_t block_start, block_length;
uint16_t filter_type;
struct filter_info* filt = NULL;
struct rar5* rar = get_context(ar);
/* Read the parameters from the input stream. */
@ -2774,7 +2794,7 @@ static int parse_filter(struct archive_read* ar, const uint8_t* p) {
}
/* Allocate a new filter. */
struct filter_info* filt = add_new_filter(rar);
filt = add_new_filter(rar);
if(filt == NULL) {
archive_set_error(&ar->archive, ENOMEM,
"Can't allocate memory for a filter descriptor.");
@ -3043,7 +3063,8 @@ static int do_uncompress_block(struct archive_read* a, const uint8_t* p) {
}
continue;
} else if(num < 262) {
} else {
/* num < 262 */
const int idx = num - 258;
const int dist = dist_cache_touch(rar, idx);
@ -3079,6 +3100,7 @@ static int scan_for_signature(struct archive_read* a) {
const uint8_t* p;
const int chunk_size = 512;
ssize_t i;
char signature[sizeof(rar5_signature_xor)];
/* If we're here, it means we're on an 'unknown territory' data.
* There's no indication what kind of data we're reading here.
@ -3092,19 +3114,23 @@ static int scan_for_signature(struct archive_read* a) {
* end of the file? If so, it would be a better approach than the
* current implementation of this function. */
rar5_signature(signature);
while(1) {
if(!read_ahead(a, chunk_size, &p))
return ARCHIVE_EOF;
for(i = 0; i < chunk_size - rar5_signature_size; i++) {
if(memcmp(&p[i], rar5_signature,
rar5_signature_size) == 0) {
for(i = 0; i < chunk_size - (int)sizeof(rar5_signature_xor);
i++) {
if(memcmp(&p[i], signature,
sizeof(rar5_signature_xor)) == 0) {
/* Consume the number of bytes we've used to
* search for the signature, as well as the
* number of bytes used by the signature
* itself. After this we should be standing
* on a valid base block header. */
(void) consume(a, i + rar5_signature_size);
(void) consume(a,
i + sizeof(rar5_signature_xor));
return ARCHIVE_OK;
}
}
@ -3314,6 +3340,8 @@ static int process_block(struct archive_read* a) {
if(rar->cstate.block_parsing_finished) {
ssize_t block_size;
ssize_t to_skip;
ssize_t cur_block_size;
/* The header size won't be bigger than 6 bytes. */
if(!read_ahead(a, 6, &p)) {
@ -3337,7 +3365,7 @@ static int process_block(struct archive_read* a) {
/* Skip block header. Next data is huffman tables,
* if present. */
ssize_t to_skip = sizeof(struct compressed_block_header) +
to_skip = sizeof(struct compressed_block_header) +
bf_byte_count(&rar->last_block_hdr) + 1;
if(ARCHIVE_OK != consume(a, to_skip))
@ -3351,7 +3379,7 @@ static int process_block(struct archive_read* a) {
* bigger than the actual data stored in this file. Remaining
* part of the data will be in another file. */
ssize_t cur_block_size =
cur_block_size =
rar5_min(rar->file.bytes_remaining, block_size);
if(block_size > rar->file.bytes_remaining) {
@ -3679,6 +3707,7 @@ static int uncompress_file(struct archive_read* a) {
static int do_unstore_file(struct archive_read* a,
struct rar5* rar, const void** buf, size_t* size, int64_t* offset)
{
size_t to_read;
const uint8_t* p;
if(rar->file.bytes_remaining == 0 && rar->main.volume > 0 &&
@ -3697,7 +3726,7 @@ static int do_unstore_file(struct archive_read* a,
}
}
size_t to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024);
to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024);
if(to_read == 0) {
return ARCHIVE_EOF;
}
@ -3866,6 +3895,18 @@ static int verify_global_checksums(struct archive_read* a) {
return verify_checksums(a);
}
/*
* Decryption function for the magic signature pattern. Check the comment near
* the `rar5_signature_xor` symbol to read the rationale behind this.
*/
static void rar5_signature(char *buf) {
size_t i;
for(i = 0; i < sizeof(rar5_signature_xor); i++) {
buf[i] = rar5_signature_xor[i] ^ 0xA1;
}
}
static int rar5_read_data(struct archive_read *a, const void **buff,
size_t *size, int64_t *offset) {
int ret;
@ -4012,19 +4053,8 @@ static int rar5_has_encrypted_entries(struct archive_read *_a) {
}
static int rar5_init(struct rar5* rar) {
ssize_t i;
memset(rar, 0, sizeof(struct rar5));
/* Decrypt the magic signature pattern. Check the comment near the
* `rar5_signature` symbol to read the rationale behind this. */
if(rar5_signature[0] == 243) {
for(i = 0; i < rar5_signature_size; i++) {
rar5_signature[i] ^= 0xA1;
}
}
if(CDE_OK != cdeque_init(&rar->cstate.filters, 8192))
return ARCHIVE_FATAL;

View File

@ -626,7 +626,8 @@ _warc_rdver(const char *buf, size_t bsz)
if (ver >= 1200U) {
if (memcmp(c, "\r\n", 2U) != 0)
ver = 0U;
} else if (ver < 1200U) {
} else {
/* ver < 1200U */
if (*c != ' ' && *c != '\t')
ver = 0U;
}

View File

@ -2613,15 +2613,14 @@ strappend_base64(struct xar *xar,
while (l > 0) {
int n = 0;
if (l > 0) {
if (base64[b[0]] < 0 || base64[b[1]] < 0)
break;
n = base64[*b++] << 18;
n |= base64[*b++] << 12;
*out++ = n >> 16;
len++;
l -= 2;
}
if (base64[b[0]] < 0 || base64[b[1]] < 0)
break;
n = base64[*b++] << 18;
n |= base64[*b++] << 12;
*out++ = n >> 16;
len++;
l -= 2;
if (l > 0) {
if (base64[*b] < 0)
break;

View File

@ -744,7 +744,8 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as,
else
dp = &defchar_used;
count = WideCharToMultiByte(to_cp, 0, ws, wslen,
as->s + as->length, (int)as->buffer_length-1, NULL, dp);
as->s + as->length,
(int)as->buffer_length - as->length - 1, NULL, dp);
if (count == 0 &&
GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
/* Expand the MBS buffer and retry. */

View File

@ -26,15 +26,15 @@
*
*/
#ifndef ARCHIVE_STRING_H_INCLUDED
#define ARCHIVE_STRING_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#ifndef ARCHIVE_STRING_H_INCLUDED
#define ARCHIVE_STRING_H_INCLUDED
#include <stdarg.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h> /* required for wchar_t on some systems */

View File

@ -34,13 +34,13 @@
* See also http://unicode.org/report/tr15/
*/
#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
struct unicode_composition_table {
uint32_t cp1;
uint32_t cp2;

View File

@ -218,8 +218,8 @@ __archive_errx(int retvalue, const char *msg)
* Also Windows version of mktemp family including _mktemp_s
* are not secure.
*/
int
__archive_mktemp(const char *tmpdir)
static int
__archive_mktempx(const char *tmpdir, wchar_t *template)
{
static const wchar_t prefix[] = L"libarchive_";
static const wchar_t suffix[] = L"XXXXXXXXXX";
@ -243,64 +243,76 @@ __archive_mktemp(const char *tmpdir)
hProv = (HCRYPTPROV)NULL;
fd = -1;
ws = NULL;
archive_string_init(&temp_name);
/* Get a temporary directory. */
if (tmpdir == NULL) {
size_t l;
wchar_t *tmp;
if (template == NULL) {
archive_string_init(&temp_name);
l = GetTempPathW(0, NULL);
if (l == 0) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
tmp = malloc(l*sizeof(wchar_t));
if (tmp == NULL) {
errno = ENOMEM;
goto exit_tmpfile;
}
GetTempPathW((DWORD)l, tmp);
archive_wstrcpy(&temp_name, tmp);
free(tmp);
} else {
if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
strlen(tmpdir)) < 0)
goto exit_tmpfile;
if (temp_name.s[temp_name.length-1] != L'/')
archive_wstrappend_wchar(&temp_name, L'/');
}
/* Get a temporary directory. */
if (tmpdir == NULL) {
size_t l;
wchar_t *tmp;
/* Check if temp_name is a directory. */
attr = GetFileAttributesW(temp_name.s);
if (attr == (DWORD)-1) {
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
l = GetTempPathW(0, NULL);
if (l == 0) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
tmp = malloc(l*sizeof(wchar_t));
if (tmp == NULL) {
errno = ENOMEM;
goto exit_tmpfile;
}
GetTempPathW((DWORD)l, tmp);
archive_wstrcpy(&temp_name, tmp);
free(tmp);
} else {
if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
strlen(tmpdir)) < 0)
goto exit_tmpfile;
if (temp_name.s[temp_name.length-1] != L'/')
archive_wstrappend_wchar(&temp_name, L'/');
}
ws = __la_win_permissive_name_w(temp_name.s);
if (ws == NULL) {
errno = EINVAL;
goto exit_tmpfile;
}
attr = GetFileAttributesW(ws);
/* Check if temp_name is a directory. */
attr = GetFileAttributesW(temp_name.s);
if (attr == (DWORD)-1) {
la_dosmaperr(GetLastError());
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
ws = __la_win_permissive_name_w(temp_name.s);
if (ws == NULL) {
errno = EINVAL;
goto exit_tmpfile;
}
attr = GetFileAttributesW(ws);
if (attr == (DWORD)-1) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
}
if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
errno = ENOTDIR;
goto exit_tmpfile;
}
}
if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
errno = ENOTDIR;
goto exit_tmpfile;
}
/*
* Create a temporary file.
*/
archive_wstrcat(&temp_name, prefix);
archive_wstrcat(&temp_name, suffix);
ep = temp_name.s + archive_strlen(&temp_name);
xp = ep - wcslen(suffix);
/*
* Create a temporary file.
*/
archive_wstrcat(&temp_name, prefix);
archive_wstrcat(&temp_name, suffix);
ep = temp_name.s + archive_strlen(&temp_name);
xp = ep - wcslen(suffix);
template = temp_name.s;
} else {
xp = wcschr(template, L'X');
if (xp == NULL) /* No X, programming error */
abort();
for (ep = xp; *ep == L'X'; ep++)
continue;
if (*ep) /* X followed by non X, programming error */
abort();
}
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) {
@ -323,20 +335,24 @@ __archive_mktemp(const char *tmpdir)
*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
free(ws);
ws = __la_win_permissive_name_w(temp_name.s);
ws = __la_win_permissive_name_w(template);
if (ws == NULL) {
errno = EINVAL;
goto exit_tmpfile;
}
/* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to
* delete this temporary file immediately when this
* file closed. */
if (template == temp_name.s) {
attr = FILE_ATTRIBUTE_TEMPORARY |
FILE_FLAG_DELETE_ON_CLOSE;
} else {
/* mkstemp */
attr = FILE_ATTRIBUTE_NORMAL;
}
h = CreateFileW(ws,
GENERIC_READ | GENERIC_WRITE | DELETE,
0,/* Not share */
NULL,
CREATE_NEW,/* Create a new file only */
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
attr,
NULL);
if (h == INVALID_HANDLE_VALUE) {
/* The same file already exists. retry with
@ -358,10 +374,23 @@ __archive_mktemp(const char *tmpdir)
if (hProv != (HCRYPTPROV)NULL)
CryptReleaseContext(hProv, 0);
free(ws);
archive_wstring_free(&temp_name);
if (template == temp_name.s)
archive_wstring_free(&temp_name);
return (fd);
}
int
__archive_mktemp(const char *tmpdir)
{
return __archive_mktempx(tmpdir, NULL);
}
int
__archive_mkstemp(wchar_t *template)
{
return __archive_mktempx(NULL, template);
}
#else
static int
@ -414,14 +443,24 @@ __archive_mktemp(const char *tmpdir)
return (fd);
}
#else
int
__archive_mkstemp(char *template)
{
int fd = -1;
fd = mkstemp(template);
if (fd >= 0)
__archive_ensure_cloexec_flag(fd);
return (fd);
}
#else /* !HAVE_MKSTEMP */
/*
* We use a private routine.
*/
int
__archive_mktemp(const char *tmpdir)
static int
__archive_mktempx(const char *tmpdir, char *template)
{
static const char num[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
@ -439,26 +478,37 @@ __archive_mktemp(const char *tmpdir)
char *tp, *ep;
fd = -1;
archive_string_init(&temp_name);
if (tmpdir == NULL) {
if (get_tempdir(&temp_name) != ARCHIVE_OK)
if (template == NULL) {
archive_string_init(&temp_name);
if (tmpdir == NULL) {
if (get_tempdir(&temp_name) != ARCHIVE_OK)
goto exit_tmpfile;
} else
archive_strcpy(&temp_name, tmpdir);
if (temp_name.s[temp_name.length-1] == '/') {
temp_name.s[temp_name.length-1] = '\0';
temp_name.length --;
}
if (la_stat(temp_name.s, &st) < 0)
goto exit_tmpfile;
} else
archive_strcpy(&temp_name, tmpdir);
if (temp_name.s[temp_name.length-1] == '/') {
temp_name.s[temp_name.length-1] = '\0';
temp_name.length --;
if (!S_ISDIR(st.st_mode)) {
errno = ENOTDIR;
goto exit_tmpfile;
}
archive_strcat(&temp_name, "/libarchive_");
tp = temp_name.s + archive_strlen(&temp_name);
archive_strcat(&temp_name, "XXXXXXXXXX");
ep = temp_name.s + archive_strlen(&temp_name);
template = temp_name.s;
} else {
tp = strchr(template, 'X');
if (tp == NULL) /* No X, programming error */
abort();
for (ep = tp; *ep == 'X'; ep++)
continue;
if (*ep) /* X followed by non X, programming error */
abort();
}
if (la_stat(temp_name.s, &st) < 0)
goto exit_tmpfile;
if (!S_ISDIR(st.st_mode)) {
errno = ENOTDIR;
goto exit_tmpfile;
}
archive_strcat(&temp_name, "/libarchive_");
tp = temp_name.s + archive_strlen(&temp_name);
archive_strcat(&temp_name, "XXXXXXXXXX");
ep = temp_name.s + archive_strlen(&temp_name);
do {
char *p;
@ -469,19 +519,33 @@ __archive_mktemp(const char *tmpdir)
int d = *((unsigned char *)p) % sizeof(num);
*p++ = num[d];
}
fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
fd = open(template, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
0600);
} while (fd < 0 && errno == EEXIST);
if (fd < 0)
goto exit_tmpfile;
__archive_ensure_cloexec_flag(fd);
unlink(temp_name.s);
if (template == temp_name.s)
unlink(temp_name.s);
exit_tmpfile:
archive_string_free(&temp_name);
if (template == temp_name.s)
archive_string_free(&temp_name);
return (fd);
}
#endif /* HAVE_MKSTEMP */
int
__archive_mktemp(const char *tmpdir)
{
return __archive_mktempx(tmpdir, NULL);
}
int
__archive_mkstemp(char *template)
{
return __archive_mktempx(NULL, template);
}
#endif /* !HAVE_MKSTEMP */
#endif /* !_WIN32 || __CYGWIN__ */
/*

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 3, 2017
.Dd January 19, 2020
.Dt ARCHIVE_WRITE_DISK 3
.Os
.Sh NAME
@ -139,6 +139,11 @@ is not specified, then SUID and SGID bits will only be restored
if the default user and group IDs of newly-created objects on disk
happen to match those specified in the archive entry.
By default, only basic permissions are restored, and umask is obeyed.
.It Cm ARCHIVE_EXTRACT_SAFE_WRITES
Extract files atomically, by first creating a unique temporary file and then
renaming it to its required destination name.
This avoids a race where an application might see a partial file (or no
file) during extraction.
.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
Refuse to extract an absolute path.
The default is to not refuse such paths.

View File

@ -253,6 +253,8 @@ struct archive_write_disk {
struct archive_entry *entry; /* Entry being extracted. */
char *name; /* Name of entry, possibly edited. */
struct archive_string _name_data; /* backing store for 'name' */
char *tmpname; /* Temporary name * */
struct archive_string _tmpname_data; /* backing store for 'tmpname' */
/* Tasks remaining for this object. */
int todo;
/* Tasks deferred until end-of-archive. */
@ -354,6 +356,7 @@ struct archive_write_disk {
static int la_opendirat(int, const char *);
static int la_mktemp(struct archive_write_disk *);
static void fsobj_error(int *, struct archive_string *, int, const char *,
const char *);
static int check_symlinks_fsobj(char *, int *, struct archive_string *,
@ -406,6 +409,30 @@ static ssize_t _archive_write_disk_data(struct archive *, const void *,
static ssize_t _archive_write_disk_data_block(struct archive *, const void *,
size_t, int64_t);
static int
la_mktemp(struct archive_write_disk *a)
{
int oerrno, fd;
mode_t mode;
archive_string_empty(&a->_tmpname_data);
archive_string_sprintf(&a->_tmpname_data, "%s.XXXXXX", a->name);
a->tmpname = a->_tmpname_data.s;
fd = __archive_mkstemp(a->tmpname);
if (fd == -1)
return -1;
mode = a->mode & 0777 & ~a->user_umask;
if (fchmod(fd, mode) == -1) {
oerrno = errno;
close(fd);
errno = oerrno;
return -1;
}
return fd;
}
static int
la_opendirat(int fd, const char *path) {
const int flags = O_CLOEXEC
@ -1826,6 +1853,14 @@ _archive_write_disk_finish_entry(struct archive *_a)
if (a->fd >= 0) {
close(a->fd);
a->fd = -1;
if (a->tmpname) {
if (rename(a->tmpname, a->name) == -1) {
archive_set_error(&a->archive, errno,
"rename failed");
ret = ARCHIVE_FATAL;
}
a->tmpname = NULL;
}
}
/* If there's an entry, we can release it now. */
archive_entry_free(a->entry);
@ -2103,17 +2138,28 @@ restore_entry(struct archive_write_disk *a)
}
if (!S_ISDIR(a->st.st_mode)) {
/* A non-dir is in the way, unlink it. */
if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
(void)clear_nochange_fflags(a);
if (unlink(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't unlink already-existing object");
return (ARCHIVE_FAILED);
if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
S_ISREG(a->st.st_mode)) {
/* Use a temporary file to extract */
if ((a->fd = la_mktemp(a)) == -1)
return ARCHIVE_FAILED;
a->pst = NULL;
en = 0;
} else {
/* A non-dir is in the way, unlink it. */
if (unlink(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't unlink already-existing "
"object");
return (ARCHIVE_FAILED);
}
a->pst = NULL;
/* Try again. */
en = create_filesystem_object(a);
}
a->pst = NULL;
/* Try again. */
en = create_filesystem_object(a);
} else if (!S_ISDIR(a->mode)) {
/* A dir is in the way of a non-dir, rmdir it. */
if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
@ -2215,6 +2261,13 @@ create_filesystem_object(struct archive_write_disk *a)
}
free(linkname_copy);
archive_string_free(&error_string);
/*
* Unlinking and linking here is really not atomic,
* but doing it right, would require us to construct
* an mktemplink() function, and then use rename(2).
*/
if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
unlink(a->name);
r = link(linkname, a->name) ? errno : 0;
/*
* New cpio and pax formats allow hardlink entries
@ -2253,6 +2306,13 @@ create_filesystem_object(struct archive_write_disk *a)
linkname = archive_entry_symlink(a->entry);
if (linkname != NULL) {
#if HAVE_SYMLINK
/*
* Unlinking and linking here is really not atomic,
* but doing it right, would require us to construct
* an mktempsymlink() function, and then use rename(2).
*/
if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
unlink(a->name);
return symlink(linkname, a->name) ? errno : 0;
#else
return (EPERM);
@ -2288,6 +2348,7 @@ create_filesystem_object(struct archive_write_disk *a)
/* POSIX requires that we fall through here. */
/* FALLTHROUGH */
case AE_IFREG:
a->tmpname = NULL;
a->fd = open(a->name,
O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, mode);
__archive_ensure_cloexec_flag(a->fd);
@ -2449,6 +2510,7 @@ _archive_write_disk_free(struct archive *_a)
archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
archive_entry_free(a->entry);
archive_string_free(&a->_name_data);
archive_string_free(&a->_tmpname_data);
archive_string_free(&a->archive.error_string);
archive_string_free(&a->path_safe);
a->archive.magic = 0;

View File

@ -26,13 +26,13 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
#include "archive_platform_acl.h"
#include "archive_acl_private.h"
#include "archive_entry.h"

View File

@ -25,15 +25,15 @@
* $FreeBSD$
*/
#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED
#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED
#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED
#include "archive.h"
#include "archive_string.h"
#include "archive_private.h"

View File

@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_private.h"
#include "archive_write_set_format_private.h"
/* A table that maps format codes to functions. */
static const
@ -76,3 +77,47 @@ archive_write_set_format(struct archive *a, int code)
archive_set_error(a, EINVAL, "No such format");
return (ARCHIVE_FATAL);
}
void
__archive_write_entry_filetype_unsupported(struct archive *a,
struct archive_entry *entry, const char *format)
{
const char *name = NULL;
switch (archive_entry_filetype(entry)) {
/*
* All formats should be able to archive regular files (AE_IFREG)
*/
case AE_IFDIR:
name = "directories";
break;
case AE_IFLNK:
name = "symbolic links";
break;
case AE_IFCHR:
name = "character devices";
break;
case AE_IFBLK:
name = "block devices";
break;
case AE_IFIFO:
name = "named pipes";
break;
case AE_IFSOCK:
name = "sockets";
break;
default:
break;
}
if (name != NULL) {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
"%s: %s format cannot archive %s",
archive_entry_pathname(entry), format, name);
} else {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
"%s: %s format cannot archive files with mode 0%lo",
archive_entry_pathname(entry), format,
(unsigned long)archive_entry_mode(entry));
}
}

View File

@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include "archive_rb.h"
#include "archive_string.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
/*
* Codec ID
@ -164,7 +165,7 @@ struct file {
mode_t mode;
uint32_t crc32;
int dir:1;
signed int dir:1;
};
struct _7zip {

View File

@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
struct ar_w {
uint64_t entry_bytes_remaining;

View File

@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
static ssize_t archive_write_cpio_data(struct archive_write *,
const void *buff, size_t s);

View File

@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
static ssize_t archive_write_newc_data(struct archive_write *,
const void *buff, size_t s);

View File

@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 19157
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
struct gnutar {
uint64_t entry_bytes_remaining;
@ -534,17 +535,9 @@ archive_write_gnutar_header(struct archive_write *a,
case AE_IFBLK: tartype = '4' ; break;
case AE_IFDIR: tartype = '5' ; break;
case AE_IFIFO: tartype = '6' ; break;
case AE_IFSOCK:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive socket");
ret = ARCHIVE_FAILED;
goto exit_write_header;
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive this (mode=0%lo)",
(unsigned long)archive_entry_mode(entry));
default: /* AE_IFSOCK and unknown */
__archive_write_entry_filetype_unsupported(
&a->archive, entry, "gnutar");
ret = ARCHIVE_FAILED;
goto exit_write_header;
}

View File

@ -289,12 +289,12 @@ struct isoent {
struct extr_rec *current;
} extr_rec_list;
int virtual:1;
signed int virtual:1;
/* If set to one, this file type is a directory.
* A convenience flag to be used as
* "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
*/
int dir:1;
signed int dir:1;
};
struct hardlink {
@ -755,9 +755,9 @@ struct iso9660 {
/* Used for making zisofs. */
struct {
int detect_magic:1;
int making:1;
int allzero:1;
signed int detect_magic:1;
signed int making:1;
signed int allzero:1;
unsigned char magic_buffer[64];
int magic_cnt;
@ -5094,13 +5094,11 @@ isofile_init_hardlinks(struct iso9660 *iso9660)
static void
isofile_free_hardlinks(struct iso9660 *iso9660)
{
struct archive_rb_node *n, *next;
struct archive_rb_node *n, *tmp;
for (n = ARCHIVE_RB_TREE_MIN(&(iso9660->hardlink_rbtree)); n;) {
next = __archive_rb_tree_iterate(&(iso9660->hardlink_rbtree),
n, ARCHIVE_RB_DIR_RIGHT);
ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(iso9660->hardlink_rbtree), tmp) {
__archive_rb_tree_remove_node(&(iso9660->hardlink_rbtree), n);
free(n);
n = next;
}
}
@ -7801,8 +7799,8 @@ struct zisofs_extract {
uint64_t pz_uncompressed_size;
size_t uncompressed_buffer_size;
int initialized:1;
int header_passed:1;
signed int initialized:1;
signed int header_passed:1;
uint32_t pz_offset;
unsigned char *block_pointers;

View File

@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
struct sparse_block {
struct sparse_block *next;
@ -713,17 +714,9 @@ archive_write_pax_header(struct archive_write *a,
}
break;
}
case AE_IFSOCK:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive socket");
return (ARCHIVE_FAILED);
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive this (type=0%lo)",
(unsigned long)
archive_entry_filetype(entry_original));
default: /* AE_IFSOCK and unknown */
__archive_write_entry_filetype_unsupported(
&a->archive, entry_original, "pax");
return (ARCHIVE_FAILED);
}
}
@ -859,13 +852,16 @@ archive_write_pax_header(struct archive_write *a,
* them do.
*/
r = get_entry_pathname(a, entry_main, &path, &path_length, sconv);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
else if (r != ARCHIVE_OK) {
} else if (r != ARCHIVE_OK) {
r = get_entry_pathname(a, entry_main, &path,
&path_length, NULL);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
}
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Can't translate pathname '%s' to %s", path,
archive_string_conversion_charset_name(sconv));
@ -873,12 +869,15 @@ archive_write_pax_header(struct archive_write *a,
sconv = NULL;/* The header charset switches to binary mode. */
}
r = get_entry_uname(a, entry_main, &uname, &uname_length, sconv);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
else if (r != ARCHIVE_OK) {
} else if (r != ARCHIVE_OK) {
r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
}
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Can't translate uname '%s' to %s", uname,
archive_string_conversion_charset_name(sconv));
@ -886,12 +885,15 @@ archive_write_pax_header(struct archive_write *a,
sconv = NULL;/* The header charset switches to binary mode. */
}
r = get_entry_gname(a, entry_main, &gname, &gname_length, sconv);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
else if (r != ARCHIVE_OK) {
} else if (r != ARCHIVE_OK) {
r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
}
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Can't translate gname '%s' to %s", gname,
archive_string_conversion_charset_name(sconv));
@ -903,13 +905,16 @@ archive_write_pax_header(struct archive_write *a,
if (linkpath == NULL) {
r = get_entry_symlink(a, entry_main, &linkpath,
&linkpath_length, sconv);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
else if (r != ARCHIVE_OK) {
} else if (r != ARCHIVE_OK) {
r = get_entry_symlink(a, entry_main, &linkpath,
&linkpath_length, NULL);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
}
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Can't translate linkname '%s' to %s", linkpath,
@ -925,21 +930,29 @@ archive_write_pax_header(struct archive_write *a,
if (hardlink != NULL) {
r = get_entry_hardlink(a, entry_main, &hardlink,
&hardlink_length, NULL);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
}
linkpath = hardlink;
linkpath_length = hardlink_length;
}
r = get_entry_pathname(a, entry_main, &path,
&path_length, NULL);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
}
r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
}
r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
if (r == ARCHIVE_FATAL)
if (r == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
return (r);
}
}
/* Store the header encoding first, to be nice to readers. */
@ -1196,24 +1209,33 @@ archive_write_pax_header(struct archive_write *a,
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA |
ARCHIVE_ENTRY_ACL_STYLE_COMPACT);
if (ret == ARCHIVE_FATAL)
if (ret == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
}
}
if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
ret = add_pax_acl(a, entry_original, pax,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
if (ret == ARCHIVE_FATAL)
if (ret == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
}
}
if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) {
ret = add_pax_acl(a, entry_original, pax,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
if (ret == ARCHIVE_FATAL)
if (ret == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
}
}
/* We use GNU-tar-compatible sparse attributes. */
@ -1352,8 +1374,11 @@ archive_write_pax_header(struct archive_write *a,
* numeric fields, though they're less critical.
*/
if (__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0,
NULL) == ARCHIVE_FATAL)
NULL) == ARCHIVE_FATAL) {
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
}
/* If we built any extended attributes, write that entry first. */
if (archive_strlen(&(pax->pax_header)) > 0) {
@ -1418,6 +1443,8 @@ archive_write_pax_header(struct archive_write *a,
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"archive_write_pax_header: "
"'x' header failed?! This can't happen.\n");
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
} else if (r < ret)
ret = r;
@ -1426,6 +1453,8 @@ archive_write_pax_header(struct archive_write *a,
sparse_list_clear(pax);
pax->entry_bytes_remaining = 0;
pax->entry_padding = 0;
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
}
@ -1437,12 +1466,16 @@ archive_write_pax_header(struct archive_write *a,
archive_strlen(&(pax->pax_header)));
if (r != ARCHIVE_OK) {
/* If a write fails, we're pretty much toast. */
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
}
/* Pad out the end of the entry. */
r = __archive_write_nulls(a, (size_t)pax->entry_padding);
if (r != ARCHIVE_OK) {
/* If a write fails, we're pretty much toast. */
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (ARCHIVE_FATAL);
}
pax->entry_bytes_remaining = pax->entry_padding = 0;
@ -1450,8 +1483,11 @@ archive_write_pax_header(struct archive_write *a,
/* Write the header for main entry. */
r = __archive_write_output(a, ustarbuff, 512);
if (r != ARCHIVE_OK)
if (r != ARCHIVE_OK) {
archive_entry_free(entry_main);
archive_string_free(&entry_name);
return (r);
}
/*
* Inform the client of the on-disk size we're using, so

View File

@ -0,0 +1,42 @@
/*-
* Copyright (c) 2020 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.
*
* $FreeBSD$
*/
#ifndef ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED
#define ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#include "archive.h"
#include "archive_entry.h"
void __archive_write_entry_filetype_unsupported(struct archive *a,
struct archive_entry *entry, const char *format);
#endif

View File

@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
struct shar {
int dump;
@ -194,8 +195,8 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
archive_entry_set_size(entry, 0);
if (archive_entry_hardlink(entry) == NULL &&
archive_entry_symlink(entry) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"shar format cannot archive this");
__archive_write_entry_filetype_unsupported(
&a->archive, entry, "shar");
return (ARCHIVE_WARN);
}
}

View File

@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
struct ustar {
uint64_t entry_bytes_remaining;
@ -512,9 +513,11 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
}
if (copy_length > 0) {
if (copy_length > USTAR_uname_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Username too long");
ret = ARCHIVE_FAILED;
if (tartype != 'x') {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC, "Username too long");
ret = ARCHIVE_FAILED;
}
copy_length = USTAR_uname_size;
}
memcpy(h + USTAR_uname_offset, p, copy_length);
@ -535,9 +538,11 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
}
if (copy_length > 0) {
if (strlen(p) > USTAR_gname_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Group name too long");
ret = ARCHIVE_FAILED;
if (tartype != 'x') {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC, "Group name too long");
ret = ARCHIVE_FAILED;
}
copy_length = USTAR_gname_size;
}
memcpy(h + USTAR_gname_offset, p, copy_length);
@ -609,16 +614,9 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break;
case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break;
case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break;
case AE_IFSOCK:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive socket");
return (ARCHIVE_FAILED);
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive this (mode=0%lo)",
(unsigned long)archive_entry_mode(entry));
default: /* AE_IFSOCK and unknown */
__archive_write_entry_filetype_unsupported(
&a->archive, entry, "ustar");
ret = ARCHIVE_FAILED;
}
}

View File

@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
struct v7tar {
uint64_t entry_bytes_remaining;
@ -491,31 +492,11 @@ format_header_v7tar(struct archive_write *a, char h[512],
case AE_IFLNK:
h[V7TAR_typeflag_offset] = '2';
break;
case AE_IFCHR:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive character device");
return (ARCHIVE_FAILED);
case AE_IFBLK:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive block device");
return (ARCHIVE_FAILED);
case AE_IFIFO:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive fifo");
return (ARCHIVE_FAILED);
case AE_IFSOCK:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive socket");
return (ARCHIVE_FAILED);
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive this (mode=0%lo)",
(unsigned long)archive_entry_mode(entry));
/* AE_IFBLK, AE_IFCHR, AE_IFIFO, AE_IFSOCK
* and unknown */
__archive_write_entry_filetype_unsupported(
&a->archive, entry, "v7tar");
ret = ARCHIVE_FAILED;
}
}

View File

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include "archive_private.h"
#include "archive_random_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
struct warc_s {
unsigned int omit_warcinfo:1;
@ -259,10 +260,8 @@ _warc_header(struct archive_write *a, struct archive_entry *entry)
return (ARCHIVE_OK);
}
/* just resort to erroring as per Tim's advice */
archive_set_error(
&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"WARC can only process regular files");
__archive_write_entry_filetype_unsupported(
&a->archive, entry, "WARC");
return (ARCHIVE_FAILED);
}
@ -332,6 +331,10 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t)
struct tm *rt;
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
struct tm timeHere;
#endif
#if defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
char strtime[100];
size_t len;
@ -340,7 +343,12 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t)
if ((rt = gmtime_r(&t, &timeHere)) == NULL)
return;
#elif defined(HAVE__GMTIME64_S)
_gmtime64_s(&timeHere, &t);
tmptime = t;
terr = _gmtime64_s(&timeHere, &tmptime);
if (terr)
rt = NULL;
else
rt = &timeHere;
#else
if ((rt = gmtime(&t)) == NULL)
return;

View File

@ -212,8 +212,8 @@ struct file {
struct heap_data data;
struct archive_string script;
int virtual:1;
int dir:1;
signed int virtual:1;
signed int dir:1;
};
struct hardlink {
@ -411,6 +411,8 @@ xar_options(struct archive_write *a, const char *key, const char *value)
if (strcmp(key, "checksum") == 0) {
if (value == NULL)
xar->opt_sumalg = CKSUM_NONE;
else if (strcmp(value, "none") == 0)
xar->opt_sumalg = CKSUM_NONE;
else if (strcmp(value, "sha1") == 0)
xar->opt_sumalg = CKSUM_SHA1;
else if (strcmp(value, "md5") == 0)
@ -429,6 +431,8 @@ xar_options(struct archive_write *a, const char *key, const char *value)
if (value == NULL)
xar->opt_compression = NONE;
else if (strcmp(value, "none") == 0)
xar->opt_compression = NONE;
else if (strcmp(value, "gzip") == 0)
xar->opt_compression = GZIP;
else if (strcmp(value, "bzip2") == 0)
@ -482,6 +486,8 @@ xar_options(struct archive_write *a, const char *key, const char *value)
if (strcmp(key, "toc-checksum") == 0) {
if (value == NULL)
xar->opt_toc_sumalg = CKSUM_NONE;
else if (strcmp(value, "none") == 0)
xar->opt_toc_sumalg = CKSUM_NONE;
else if (strcmp(value, "sha1") == 0)
xar->opt_toc_sumalg = CKSUM_SHA1;
else if (strcmp(value, "md5") == 0)
@ -696,13 +702,37 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s)
else
run = ARCHIVE_Z_FINISH;
/* Compress file data. */
r = compression_code(&(a->archive), &(xar->stream), run);
if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
return (ARCHIVE_FATAL);
for (;;) {
r = compression_code(&(a->archive), &(xar->stream),
run);
if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
return (ARCHIVE_FATAL);
if (xar->stream.avail_out == 0 ||
run == ARCHIVE_Z_FINISH) {
size = sizeof(xar->wbuff) -
xar->stream.avail_out;
checksum_update(&(xar->a_sumwrk), xar->wbuff,
size);
xar->cur_file->data.length += size;
if (write_to_temp(a, xar->wbuff,
size) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
if (r == ARCHIVE_OK) {
/* Output buffer was full */
xar->stream.next_out = xar->wbuff;
xar->stream.avail_out =
sizeof(xar->wbuff);
} else {
/* ARCHIVE_EOF - We are done */
break;
}
} else {
/* Compressor wants more input */
break;
}
}
rsize = s - xar->stream.avail_in;
checksum_update(&(xar->e_sumwrk), buff, rsize);
size = sizeof(xar->wbuff) - xar->stream.avail_out;
checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
}
#if !defined(_WIN32) || defined(__CYGWIN__)
if (xar->bytes_remaining ==
@ -739,12 +769,9 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s)
if (xar->cur_file->data.compression == NONE) {
if (write_to_temp(a, buff, size) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
} else {
if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
xar->cur_file->data.length += size;
}
xar->bytes_remaining -= rsize;
xar->cur_file->data.length += size;
return (rsize);
}
@ -878,11 +905,15 @@ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
{
char timestr[100];
struct tm tm;
#if defined(HAVE__GMTIME64_S)
__time64_t tmptime;
#endif
#if defined(HAVE_GMTIME_R)
gmtime_r(&t, &tm);
#elif defined(HAVE__GMTIME64_S)
_gmtime64_s(&tm, &t);
tmptime = t;
_gmtime64_s(&tm, &tmptime);
#else
memcpy(&tm, gmtime(&t), sizeof(tm));
#endif
@ -2103,7 +2134,7 @@ file_gen_utility_names(struct archive_write *a, struct file *file)
while (len > 0) {
size_t ll = len;
if (len > 0 && p[len-1] == '/') {
if (p[len-1] == '/') {
p[len-1] = '\0';
len--;
}
@ -2532,13 +2563,11 @@ file_init_hardlinks(struct xar *xar)
static void
file_free_hardlinks(struct xar *xar)
{
struct archive_rb_node *n, *next;
struct archive_rb_node *n, *tmp;
for (n = ARCHIVE_RB_TREE_MIN(&(xar->hardlink_rbtree)); n;) {
next = __archive_rb_tree_iterate(&(xar->hardlink_rbtree),
n, ARCHIVE_RB_DIR_RIGHT);
ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) {
__archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n);
free(n);
n = next;
}
}

View File

@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include "archive_private.h"
#include "archive_random_private.h"
#include "archive_write_private.h"
#include "archive_write_set_format_private.h"
#ifndef HAVE_ZLIB_H
#include "archive_crc32.h"
@ -526,8 +527,8 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
/* Ignore types of entries that we don't support. */
type = archive_entry_filetype(entry);
if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Filetype not supported");
__archive_write_entry_filetype_unsupported(
&a->archive, entry, "zip");
return ARCHIVE_FAILED;
};
@ -1372,10 +1373,28 @@ dos_time(const time_t unix_time)
{
struct tm *t;
unsigned int dt;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/* This will not preserve time when creating/extracting the archive
* on two systems with different time zones. */
#if defined(HAVE_LOCALTIME_R)
t = localtime_r(&unix_time, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = unix_time;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
t = NULL;
else
t = &tmbuf;
#else
t = localtime(&unix_time);
#endif
/* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */
if (t->tm_year < 1980 - 1900)

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd December 3, 2019
.Dd January 31, 2020
.Dt ARCHIVE_WRITE_OPTIONS 3
.Os
.Sh NAME
@ -170,33 +170,125 @@ only to modules whose name matches
.\"
.Sh OPTIONS
.Bl -tag -compact -width indent
.It Filter b64encode
.Bl -tag -compact -width indent
.It Cm mode
The value is interpreted as octal digits specifying the file mode.
.It Cm name
The value specifies the file name.
.El
.It Filter bzip2
.Bl -tag -compact -width indent
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
bzip2 compression level. Supported values are from 1 to 9.
.El
.It Filter gzip
.Bl -tag -compact -width indent
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
gzip compression level.
gzip compression level. Supported values are from 0 to 9.
.It Cm timestamp
Store timestamp. This is enabled by default.
.El
.It Filter lrzip
.Bl -tag -compact -width indent
.It Cm compression Ns = Ns Ar type
Use
.Ar type
as compression method.
Supported values are
.Dq bzip2 ,
.Dq gzipi ,
.Dq lzo
.Pq ultra fast ,
and
.Dq zpaq
.Pq best, extremely slow .
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
lrzip compression level. Supported values are from 1 to 9.
.El
.It Filter lz4
.Bl -tag -compact -width indent
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
lz4 compression level. Supported values are from 0 to 9.
.It Cm stream-checksum
Enable stream checksum. This is enabled by default.
.It Cm block-checksum
Enable block checksum. This is disabled by default.
.It Cm block-size
The value is interpreted as a decimal integer specifying the
lz4 compression block size. Supported values are from 4 to 7
.Pq default .
.It Cm block-dependence
Use the previous block of the block being compressed for
a compression dictionary to improve compression ratio.
This is disabled by default.
.El
.It Filter lzop
.Bl -tag -compact -width indent
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
lzop compression level. Supported values are from 1 to 9.
.El
.It Filter uuencode
.Bl -tag -compact -width indent
.It Cm mode
The value is interpreted as octal digits specifying the file mode.
.It Cm name
The value specifies the file name.
.El
.It Filter xz
.Bl -tag -compact -width indent
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
compression level.
compression level. Supported values are from 0 to 9.
.It Cm threads
The value is interpreted as a decimal integer specifying the
number of threads for multi-threaded lzma compression.
If supported, the default value is read from
.Fn lzma_cputhreads .
.El
.It Format mtree
.It Filter zstd
.Bl -tag -compact -width indent
.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname
Enable a particular keyword in the mtree output.
Prefix with an exclamation mark to disable the corresponding keyword.
The default is equivalent to
.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname .
.It Cm all
Enables all of the above keywords.
.It Cm use-set
Enables generation of
.Cm /set
lines that specify default values for the following files and/or directories.
.It Cm indent
XXX needs explanation XXX
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
compression level. Supported values are from 1 to 22.
.El
.It Format 7zip
.Bl -tag -compact -width indent
.It Cm compression
The value is one of
.Dq store ,
.Dq deflate ,
.Dq bzip2 ,
.Dq lzma1 ,
.Dq lzma2
or
.Dq ppmd
to indicate how the following entries should be compressed.
Note that this setting is ignored for directories, symbolic links,
and other special entries.
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
compression level.
Values between 0 and 9 are supported.
The interpretation of the compression level depends on the chosen
compression method.
.El
.It Format cpio
.Bl -tag -compact -width indent
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file names.
.El
.It Format gnutar
.Bl -tag -compact -width indent
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file, group and user names.
.El
.It Format iso9660 - volume metadata
These options are used to set standard ISO9660 metadata.
@ -404,10 +496,33 @@ Specifies a filename that should not be compressed when using
This option can be provided multiple times to suppress compression
on many files.
.El
.It Format mtree
.Bl -tag -compact -width indent
.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname
Enable a particular keyword in the mtree output.
Prefix with an exclamation mark to disable the corresponding keyword.
The default is equivalent to
.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname .
.It Cm all
Enables all of the above keywords.
.It Cm use-set
Enables generation of
.Cm /set
lines that specify default values for the following files and/or directories.
.It Cm indent
XXX needs explanation XXX
.El
.It Format newc
.Bl -tag -compact -width indent
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file names.
.El
.It Format pax
.Bl -tag -compact -width indent
.It Cm hdrcharset
This sets the character set used for filenames, uname and gname.
The value is used as a character set name that will be
used when translating file, group and user names.
The value is one of
.Dq BINARY
or
@ -430,26 +545,61 @@ and
.Dq SCHILY.xattr
headers are written.
.El
.It Format 7zip
.It Format ustar
.Bl -tag -compact -width indent
.It Cm compression
The value is one of
.Dq store ,
.Dq deflate ,
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file, group and user names.
.El
.It Format v7tar
.Bl -tag -compact -width indent
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file, group and user names.
.El
.It Format warc
.Bl -tag -compact -width indent
.It Cm omit-warcinfo
Set to
.Dq true
to disable output of the warcinfo record.
.El
.It Format xar
.Bl -tag -compact -width indent
.It Cm checksum Ns = Ns Ar type
Use
.Ar type
as file checksum method.
Supported values are
.Dq none ,
.Dq md5 ,
and
.Dq sha1
.Pq default .
.It Cm compression Ns = Ns Ar type
Use
.Ar type
as compression method.
Supported values are
.Dq none ,
.Dq bzip2 ,
.Dq lzma1 ,
.Dq lzma2
or
.Dq ppmd
to indicate how the following entries should be compressed.
Note that this setting is ignored for directories, symbolic links,
and other special entries.
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
compression level.
Values between 0 and 9 are supported.
The interpretation of the compression level depends on the chosen
compression method.
.Dq gzip
.Pq default ,
.Dq lzma
and
.Dq xz .
.It Cm compression_level
The value is a decimal integer from 1 to 9 specifying the compression level.
.It Cm toc-checksum Ns = Ns Ar type
Use
.Ar type
as table of contents checksum method.
Supported values are
.Dq none ,
.Dq md5
and
.Dq sha1
.Pq default .
.El
.It Format zip
.Bl -tag -compact -width indent
@ -470,6 +620,20 @@ A compression level of 0 switches the compression method to
other values will enable
.Dq deflate
compression with the given level.
.It Cm encryption
Enable encryption using traditional zip encryption.
.It Cm encryption Ns = Ns Ar type
Use
.Ar type
as encryption type.
Supported values are
.Dq zipcrypt
.Pq traditional zip encryption ,
.Dq aes128
.Pq WinZip AES-128 encryption
and
.Dq aes256
.Pq WinZip AES-256 encryption .
.It Cm experimental
This boolean option enables or disables experimental Zip features
that may not be compatible with other Zip implementations.
@ -478,7 +642,8 @@ This boolean option disables CRC calculations.
All CRC fields are set to zero.
It should not be used except for testing purposes.
.It Cm hdrcharset
This sets the character set used for filenames.
The value is used as a character set name that will be
used when translating file names.
.It Cm zip64
Zip64 extensions provide additional file size information
for entries larger than 4 GiB.

View File

@ -24,12 +24,13 @@
*
*/
#ifndef ARCHIVE_XXHASH_H_INCLUDED
#define ARCHIVE_XXHASH_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_XXHASH_H
#define ARCHIVE_XXHASH_H
typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;

View File

@ -25,13 +25,13 @@
* $FreeBSD$
*/
#ifndef FILTER_FORK_H
#define FILTER_FORK_H
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef FILTER_FORK_H
#define FILTER_FORK_H
pid_t
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout);

View File

@ -30,7 +30,7 @@ __FBSDID("$FreeBSD$");
static void
test_format_filter_by_ext(const char *output_file,
int format_id, int filter_id, int dot_stored, char * def_ext)
int format_id, int filter_id, int dot_stored, const char * def_ext)
{
struct archive_entry *ae;
struct archive *a;

View File

@ -156,7 +156,7 @@ DEFINE_TEST(test_compat_zip_4)
size_t s;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
/* SFX files require seek support. */
assert((a = archive_read_new()) != NULL);
@ -214,7 +214,7 @@ DEFINE_TEST(test_compat_zip_5)
size_t s;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
/* Verify with seek support.
* Everything works correctly here. */
@ -370,7 +370,7 @@ DEFINE_TEST(test_compat_zip_6)
size_t s;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
@ -402,7 +402,7 @@ DEFINE_TEST(test_compat_zip_7)
int i;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
for (i = 1; i < 1000; ++i) {
assert((a = archive_read_new()) != NULL);
@ -436,7 +436,7 @@ DEFINE_TEST(test_compat_zip_8)
size_t s;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));

View File

@ -119,7 +119,8 @@ test_fuzz(const struct files *filesets)
for (i = 0; filesets[n].names[i] != NULL; ++i)
{
char *newraw;
tmp = slurpfile(&size, filesets[n].names[i]);
tmp = slurpfile(&size, "%s",
filesets[n].names[i]);
newraw = realloc(rawimage, oldsize + size);
if (!assert(newraw != NULL))
{

View File

@ -120,7 +120,7 @@ DEFINE_TEST(test_read_extract)
assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff, BUFF_SIZE));
/* Restore first entry with _EXTRACT_PERM. */
failure("Error reading first entry", i);
failure("Error reading first entry");
assertA(0 == archive_read_next_header(a, &ae));
assertA(0 == archive_read_extract(a, ae, ARCHIVE_EXTRACT_PERM));
/* Rest of entries get restored with no flags. */

View File

@ -87,7 +87,7 @@ test_copy(int use_open_fd)
* An archive file has no entry.
*/
static void
test_empty_archive()
test_empty_archive(void)
{
const char *refname = "test_read_format_7zip_empty_archive.7z";
struct archive_entry *ae;
@ -119,7 +119,7 @@ test_empty_archive()
* in the archive file except for a header.
*/
static void
test_empty_file()
test_empty_file(void)
{
const char *refname = "test_read_format_7zip_empty_file.7z";
struct archive_entry *ae;
@ -609,7 +609,7 @@ test_bcj(const char *refname)
* Extract a file compressed with PPMd.
*/
static void
test_ppmd()
test_ppmd(void)
{
const char *refname = "test_read_format_7zip_ppmd.7z";
struct archive_entry *ae;
@ -663,7 +663,7 @@ test_ppmd()
}
static void
test_symname()
test_symname(void)
{
const char *refname = "test_read_format_7zip_symbolic_name.7z";
struct archive_entry *ae;
@ -720,7 +720,8 @@ DEFINE_TEST(test_read_format_7zip)
/* Extracting with liblzma */
if (ARCHIVE_OK != archive_read_support_filter_xz(a)) {
skipping("7zip:lzma decoding is not supported on this platform");
skipping("7zip:lzma decoding is not supported on this "
"platform");
} else {
test_symname();
test_extract_all_files("test_read_format_7zip_copy_2.7z");
@ -795,7 +796,8 @@ DEFINE_TEST(test_read_format_7zip_lzma1)
/* Extracting with liblzma */
if (ARCHIVE_OK != archive_read_support_filter_xz(a)) {
skipping("7zip:lzma decoding is not supported on this platform");
skipping("7zip:lzma decoding is not supported on this "
"platform");
} else {
test_plain_header("test_read_format_7zip_lzma1.7z");
test_extract_all_files("test_read_format_7zip_lzma1_2.7z");
@ -804,6 +806,7 @@ DEFINE_TEST(test_read_format_7zip_lzma1)
test_bcj("test_read_format_7zip_bcj2_lzma1_1.7z");
test_bcj("test_read_format_7zip_bcj2_lzma1_2.7z");
test_delta_lzma("test_read_format_7zip_delta_lzma1.7z");
test_delta_lzma("test_read_format_7zip_delta4_lzma1.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
@ -816,13 +819,15 @@ DEFINE_TEST(test_read_format_7zip_lzma2)
/* Extracting with liblzma */
if (ARCHIVE_OK != archive_read_support_filter_xz(a)) {
skipping("7zip:lzma decoding is not supported on this platform");
skipping("7zip:lzma decoding is not supported on this "
"platform");
} else {
test_plain_header("test_read_format_7zip_lzma2.7z");
test_bcj("test_read_format_7zip_bcj_lzma2.7z");
test_bcj("test_read_format_7zip_bcj2_lzma2_1.7z");
test_bcj("test_read_format_7zip_bcj2_lzma2_2.7z");
test_delta_lzma("test_read_format_7zip_delta_lzma2.7z");
test_delta_lzma("test_read_format_7zip_delta4_lzma2.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,407 @@
begin 664 test_read_format_7zip_delta4_lzma1.7z
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
$I($`````
`
end

View File

@ -0,0 +1,407 @@
begin 664 test_read_format_7zip_delta4_lzma2.7z
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
+`14&`0`@@*2!````
`
end

View File

@ -35,43 +35,55 @@ DEFINE_TEST(test_read_format_7zip_packinfo_digests)
extract_reference_file(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,
archive_read_open_filename(a, refname, 10240));
if (ARCHIVE_OK != archive_read_support_filter_xz(a)) {
skipping("7zip:lzma decoding is not supported on this "
"platform");
} else {
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 regular file1. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
assertEqualString("a.txt", archive_entry_pathname(ae));
assertEqualInt(1576808819, archive_entry_mtime(ae));
assertEqualInt(4, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
assertEqualInt(4, archive_read_data(a, buff, sizeof(buff)));
assertEqualMem(buff, "aaa\n", 4);
/* Verify regular file1. */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
assertEqualString("a.txt", archive_entry_pathname(ae));
assertEqualInt(1576808819, archive_entry_mtime(ae));
assertEqualInt(4, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
assertEqualInt(4, archive_read_data(a, buff, sizeof(buff)));
assertEqualMem(buff, "aaa\n", 4);
/* Verify regular file2. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
assertEqualString("b.txt", archive_entry_pathname(ae));
assertEqualInt(1576808819, archive_entry_mtime(ae));
assertEqualInt(4, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
assertEqualInt(4, archive_read_data(a, buff, sizeof(buff)));
assertEqualMem(buff, "bbb\n", 4);
/* Verify regular file2. */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
assertEqualString("b.txt", archive_entry_pathname(ae));
assertEqualInt(1576808819, archive_entry_mtime(ae));
assertEqualInt(4, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
assertEqualInt(4, archive_read_data(a, buff, sizeof(buff)));
assertEqualMem(buff, "bbb\n", 4);
assertEqualInt(2, archive_file_count(a));
assertEqualInt(2, archive_file_count(a));
/* End of archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* End of archive. */
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_next_header(a, &ae));
/* Verify archive format. */
assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
/* Verify archive format. */
assertEqualIntA(a, ARCHIVE_FILTER_NONE,
archive_filter_code(a, 0));
assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP,
archive_format(a));
/* Close the archive. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
/* Close the archive. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -214,8 +214,9 @@ verify_archive_file(const char *name, struct archive_contents *ac)
* Any byte before the expected
* data must be NULL.
*/
failure("%s: pad at offset %d "
"should be zero", name, actual.o);
failure("%s: pad at offset %jd "
"should be zero", name,
(intmax_t)actual.o);
assertEqualInt(c, 0);
} else if (actual.o == expect.o) {
/*

View File

@ -1256,3 +1256,18 @@ DEFINE_TEST(test_read_format_rar5_different_winsize_on_merge)
EPILOGUE();
}
DEFINE_TEST(test_read_format_rar5_block_size_is_too_small)
{
char buf[4096];
PROLOGUE("test_read_format_rar5_block_size_is_too_small.rar");
/* This file is damaged, so those functions should return failure.
* Additionally, SIGSEGV shouldn't be raised during execution
* of those functions. */
assertA(archive_read_next_header(a, &ae) != ARCHIVE_OK);
assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
EPILOGUE();
}

View File

@ -0,0 +1,8 @@
begin 644 test_read_format_rar5_block_size_is_too_small.rar
M4F%R(1H'`0"-[P+2``+'(!P,("`@N`,!`B`@("`@("`@("`@("`@("#_("`@
M("`@("`@("`@((:Q;2!4-'-^4B`!((WO`M(``O\@$/\@-R`@("`@("`@("`@
M``X@("`@("`@____("`@("`@(/\@("`@("`@("`@("#_(+6U,2"UM;6UM[CU
M)B`@*(0G(`!.`#D\3R``(/__(,+_````-0#_($&%*/HE=C+N`"```"```"`D
J`)$#("#_("#__P`@__\@_R#_("`@("`@("#_("#__R`@(/__("#__R`"
`
end

View File

@ -194,7 +194,7 @@ test_basic(void)
verify_basic(a, 1);
/* Verify with streaming reader. */
p = slurpfile(&s, refname);
p = slurpfile(&s, "%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));
@ -264,7 +264,7 @@ test_info_zip_ux(void)
verify_info_zip_ux(a, 1);
/* Verify with streaming reader. */
p = slurpfile(&s, refname);
p = slurpfile(&s, "%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));
@ -328,7 +328,7 @@ test_extract_length_at_end(void)
verify_extract_length_at_end(a, 1);
/* Verify extraction with streaming reader. */
p = slurpfile(&s, refname);
p = slurpfile(&s, "%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));
@ -347,7 +347,7 @@ test_symlink(void)
struct archive_entry *ae;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
/* Symlinks can only be extracted with the seeking reader. */
assert((a = archive_read_new()) != NULL);

View File

@ -90,7 +90,7 @@ DEFINE_TEST(test_read_format_zip_utf8_paths)
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
/* Verify with streaming reader. */
p = slurpfile(&s, refname);
p = slurpfile(&s, "%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));

View File

@ -38,7 +38,7 @@ verify(const char *refname)
struct archive_entry *ae;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
/* Symlinks can only be extracted with the seeking reader. */
assert((a = archive_read_new()) != NULL);

View File

@ -80,7 +80,7 @@ DEFINE_TEST(test_read_format_zip_extra_padding)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Verify with streaming reader. */
p = slurpfile(&s, refname);
p = slurpfile(&s, "%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));

View File

@ -56,7 +56,7 @@ DEFINE_TEST(test_read_format_zip_high_compression)
}
extract_reference_file(refname);
p = slurpfile(&archive_size, refname);
p = slurpfile(&archive_size, "%s", refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));

View File

@ -40,7 +40,7 @@ DEFINE_TEST(test_read_format_zip_jar)
char data[16];
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip_seekable(a));

View File

@ -76,7 +76,7 @@ DEFINE_TEST(test_read_format_zip_mac_metadata)
};
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
/* Mac metadata can only be extracted with the seeking reader. */
assert((a = archive_read_new()) != NULL);

View File

@ -46,7 +46,7 @@ test_malformed1(void)
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
/* Verify with streaming reader. */
p = slurpfile(&s, refname);
p = slurpfile(&s, "%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));

View File

@ -103,7 +103,7 @@ DEFINE_TEST(test_read_format_zip_msdos)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Verify with streaming reader. */
p = slurpfile(&s, refname);
p = slurpfile(&s, "%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));

View File

@ -34,7 +34,7 @@ DEFINE_TEST(test_read_format_zip_nested)
struct archive_entry *ae;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
/* Inspect outer Zip */
assert((a = archive_read_new()) != NULL);

View File

@ -40,7 +40,7 @@ DEFINE_TEST(test_read_format_zip_nofiletype)
char data[16];
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip_seekable(a));

View File

@ -34,7 +34,7 @@ verify_padded_archive(const char *refname)
struct archive_entry *ae;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip_seekable(a));

View File

@ -37,7 +37,7 @@ DEFINE_TEST(test_read_format_zip_sfx)
struct archive_entry *ae;
extract_reference_file(refname);
p = slurpfile(&s, refname);
p = slurpfile(&s, "%s", refname);
/* Symlinks can only be extracted with the seeking reader. */
assert((a = archive_read_new()) != NULL);

Some files were not shown because too many files have changed in this diff Show More