MFV r302003,r302037,r302038,r302056:

Update libarchive to 3.2.1 (bugfix and security fix release)

List of vendor fixes:
- fix exploitable heap overflow vulnerability in Rar decompression
  (vendor issue 719, CVE-2016-4302, TALOS-2016-0154)
- fix exploitable stack based buffer overflow vulnebarility in mtree
  parse_device functionality (vendor PR 715, CVE-2016-4301, TALOS-2016-0153)
- fix exploitable heap overflow vulnerability in 7-zip read_SubStreamsInfo
  (vendor issue 718, CVE-2016-4300, TALOS-2016-152)
- fix integer overflow when computing location of volume descriptor
  (vendor issue 717)
- fix buffer overflow when reading a crafred rar archive (vendor issue 521)
- fix possible buffer overflow when reading ISO9660 archives on machines
  where sizeof(int) < sizeof(size_t) (vendor issue 711)
- tar and cpio should fail if an input file named on the command line is
  missing (vendor issue 708)
- fix incorrect writing of gnutar filenames that are exactly 512 bytes
  long (vendor issue 682)
- allow tests to be run from paths that are equal or longer than 128
  characters (vendor issue 657)
- add memory allocation errors in archive_entry_xattr.c (vendor PR 603)
- remove dead code in archive_entry_xattr_add_entry() (vendor PR 716)
- fix broken decryption of ZIP files (vendor issue 553)
- manpage style, typo and description fixes

Post-3.2.1 vendor fixes:
- fix typo in cpio version reporting (Vendor PR 725, 726)
- fix argument range of ctype functions in libarchive_fe/passphrase.c
- fix ctype use and avoid empty loop bodies in WARC reader

MFC after:	1 week
Security:	CVE-2016-4300, CVE-2016-4301, CVE-2016-4302
Approved by:	re (kib)
This commit is contained in:
Martin Matuska 2016-06-22 07:49:59 +00:00
commit f061a2215f
37 changed files with 594 additions and 171 deletions

View File

@ -1,3 +1,8 @@
Jun 20, 2016: libarchive 3.2.1 released
This fixes a handful of security and other critical issues with 3.2.0
May 01, 2016: libarchive 3.2.0 released
Apr 09, 2016: libarchive 3.1.901a released
Another test release in preparation for 3.2.0

View File

@ -2534,18 +2534,36 @@ usage(const char *program)
static char *
get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
size_t tried_size, buff_size;
char *buff, *tried, *pwd = NULL, *p = NULL;
#ifdef PATH_MAX
buff_size = PATH_MAX;
#else
buff_size = 8192;
#endif
buff = calloc(buff_size, 1);
if (buff == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* Allocate a buffer to hold the various directories we checked. */
tried_size = buff_size * 2;
tried = calloc(tried_size, 1);
if (tried == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* If a dir was specified, try that */
if (d != NULL) {
pwd = NULL;
snprintf(buff, sizeof(buff), "%s", d);
snprintf(buff, buff_size, "%s", d);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
goto failure;
}
@ -2559,48 +2577,48 @@ get_refdir(const char *d)
pwd[strlen(pwd) - 1] = '\0';
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
snprintf(buff, buff_size, "%s", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd);
snprintf(buff, buff_size, "%s/test", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(PROGRAM_ALIAS)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#endif
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
snprintf(buff, buff_size, "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
snprintf(buff, buff_size, "%s/test", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
}
failure:
@ -2615,7 +2633,12 @@ get_refdir(const char *d)
success:
free(p);
free(pwd);
return strdup(buff);
free(tried);
/* Copy result into a fresh buffer to reduce memory usage. */
p = strdup(buff);
free(buff);
return p;
}
int

View File

@ -498,7 +498,7 @@ long_help(void)
static void
version(void)
{
fprintf(stdout,"bsdcpio %s -- %s\n",
fprintf(stdout,"bsdcpio %s - %s\n",
BSDCPIO_VERSION_STRING,
archive_version_details());
exit(0);

View File

@ -2535,18 +2535,36 @@ usage(const char *program)
static char *
get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
size_t tried_size, buff_size;
char *buff, *tried, *pwd = NULL, *p = NULL;
#ifdef PATH_MAX
buff_size = PATH_MAX;
#else
buff_size = 8192;
#endif
buff = calloc(buff_size, 1);
if (buff == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* Allocate a buffer to hold the various directories we checked. */
tried_size = buff_size * 2;
tried = calloc(tried_size, 1);
if (tried == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* If a dir was specified, try that */
if (d != NULL) {
pwd = NULL;
snprintf(buff, sizeof(buff), "%s", d);
snprintf(buff, buff_size, "%s", d);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
goto failure;
}
@ -2560,48 +2578,48 @@ get_refdir(const char *d)
pwd[strlen(pwd) - 1] = '\0';
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
snprintf(buff, buff_size, "%s", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd);
snprintf(buff, buff_size, "%s/test", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(PROGRAM_ALIAS)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#endif
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
snprintf(buff, buff_size, "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
snprintf(buff, buff_size, "%s/test", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
}
failure:
@ -2616,7 +2634,12 @@ get_refdir(const char *d)
success:
free(p);
free(pwd);
return strdup(buff);
free(tried);
/* Copy result into a fresh buffer to reduce memory usage. */
p = strdup(buff);
free(buff);
return p;
}
int

View File

@ -0,0 +1,52 @@
/*-
* Copyright (c) 2016 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
__FBSDID("$FreeBSD$");
DEFINE_TEST(test_missing_file)
{
int r;
assertMakeFile("file1", 0644, "file1");
assertMakeFile("file2", 0644, "file2");
assertMakeFile("filelist1", 0644, "file1\nfile2\n");
r = systemf("%s -o <filelist1 >stdout1 2>stderr1", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "stderr1");
assertMakeFile("filelist2", 0644, "file1\nfile2\nfile3\n");
r = systemf("%s -o <filelist2 >stdout2 2>stderr2", testprog);
assert(r != 0);
assertMakeFile("filelist3", 0644, "");
r = systemf("%s -o <filelist3 >stdout3 2>stderr3", testprog);
assertEqualInt(r, 0);
assertTextFileContents("1 block\n", "stderr3");
assertMakeFile("filelist4", 0644, "file3\n");
r = systemf("%s -o <filelist4 >stdout4 2>stderr4", testprog);
assert(r != 0);
}

View File

@ -59,8 +59,8 @@ verify(const char *p, size_t s)
++q; --s;
/* Separator. */
failure("Version: %s", p);
assertEqualMem(q, "-- ", 3);
q += 3; s -= 3;
assertEqualMem(q, "- ", 2);
q += 2; s -= 2;
/* libarchive name and version number */
assert(s > 11);
failure("Version: %s", p);

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 3002000
#define ARCHIVE_VERSION_NUMBER 3002001
#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.2.0"
#define ARCHIVE_VERSION_ONLY_STRING "3.2.1"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);

View File

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

View File

@ -91,16 +91,11 @@ archive_entry_xattr_add_entry(struct archive_entry *entry,
{
struct ae_xattr *xp;
for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
;
if ((xp = (struct ae_xattr *)malloc(sizeof(struct ae_xattr))) == NULL)
/* XXX Error XXX */
return;
__archive_errx(1, "Out of memory");
if ((xp->name = strdup(name)) == NULL)
/* XXX Error XXX */
return;
__archive_errx(1, "Out of memory");
if ((xp->value = malloc(size)) != NULL) {
memcpy(xp->value, value, size);

View File

@ -126,6 +126,11 @@ static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
{
if (p->Base == 0 || p->Size != size)
{
/* RestartModel() below assumes that p->Size >= UNIT_SIZE
(see the calculation of m->MinContext). */
if (size < UNIT_SIZE) {
return False;
}
Ppmd7_Free(p, alloc);
p->AlignOffset =
#ifdef PPMD_32BIT

View File

@ -2153,6 +2153,9 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
return (-1);
if (UMAX_ENTRY < f[i].numUnpackStreams)
return (-1);
if (unpack_streams > SIZE_MAX - UMAX_ENTRY) {
return (-1);
}
unpack_streams += (size_t)f[i].numUnpackStreams;
}
if ((p = header_bytes(a, 1)) == NULL)

View File

@ -1091,7 +1091,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
/* This condition is unlikely; by way of caution. */
vd = &(iso9660->joliet);
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location;
skipsize = __archive_read_consume(a, skipsize);
if (skipsize < 0)
return ((int)skipsize);
@ -1129,7 +1129,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
&& iso9660->seenJoliet) {
/* Switch reading data from primary to joliet. */
vd = &(iso9660->joliet);
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location;
skipsize -= iso9660->current_position;
skipsize = __archive_read_consume(a, skipsize);
if (skipsize < 0)

View File

@ -1712,6 +1712,7 @@ lha_crc16(uint16_t crc, const void *pp, size_t len)
for (;len >= 8; len -= 8) {
/* This if statement expects compiler optimization will
* remove the stament which will not be executed. */
#undef bswap16
#if defined(_MSC_VER) && _MSC_VER >= 1400 /* Visual Studio */
# define bswap16(x) _byteswap_ushort(x)
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8) \

View File

@ -1385,12 +1385,12 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
"Missing number");
return ARCHIVE_WARN;
}
numbers[argc++] = (unsigned long)mtree_atol(&p);
if (argc > MAX_PACK_ARGS) {
if (argc >= MAX_PACK_ARGS) {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
"Too many arguments");
return ARCHIVE_WARN;
}
numbers[argc++] = (unsigned long)mtree_atol(&p);
}
if (argc < 2) {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,

View File

@ -2127,6 +2127,12 @@ parse_codes(struct archive_read *a)
rar->range_dec.Stream = &rar->bytein;
__archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context);
if (rar->dictionary_size == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid zero dictionary size");
return (ARCHIVE_FATAL);
}
if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,
rar->dictionary_size, &g_szalloc))
{
@ -2884,11 +2890,10 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer,
}
windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
if(windowoffs + length <= lzss_size(&rar->lzss))
if(windowoffs + length <= lzss_size(&rar->lzss)) {
memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
length);
else
{
} else if (length <= lzss_size(&rar->lzss)) {
firstpart = lzss_size(&rar->lzss) - windowoffs;
if (firstpart < 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@ -2900,9 +2905,14 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer,
&rar->lzss.window[windowoffs], firstpart);
memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
&rar->lzss.window[0], length - firstpart);
} else
} else {
memcpy(&rar->unp_buffer[rar->unp_offset],
&rar->lzss.window[windowoffs], length);
}
} else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Bad RAR file data");
return (ARCHIVE_FATAL);
}
rar->unp_offset += length;
if (rar->unp_offset >= rar->unp_buffer_size)

View File

@ -535,7 +535,8 @@ xstrpisotime(const char *s, char **endptr)
/* as a courtesy to our callers, and since this is a non-standard
* routine, we skip leading whitespace */
for (; isspace(*s); s++);
while (isspace((unsigned char)*s))
++s;
/* read year */
if ((tm.tm_year = strtoi_lim(s, &s, 1583, 4095)) < 0 || *s++ != '-') {
@ -639,7 +640,9 @@ _warc_rdtyp(const char *buf, size_t bsz)
return WT_NONE;
}
/* overread whitespace */
for (val += sizeof(_key) - 1U; val < eob && isspace(*val); val++);
val += sizeof(_key) - 1U;
while (val < eob && isspace((unsigned char)*val))
++val;
if (val + 8U > eob) {
;
@ -676,7 +679,9 @@ _warc_rduri(const char *buf, size_t bsz)
return res;
}
/* overread whitespace */
for (val += sizeof(_key) - 1U; val < eob && isspace(*val); val++);
val += sizeof(_key) - 1U;
while (val < eob && isspace((unsigned char)*val))
++val;
/* overread URL designators */
if ((uri = xmemmem(val, eob - val, "://", 3U)) == NULL) {
@ -692,7 +697,8 @@ _warc_rduri(const char *buf, size_t bsz)
/* also massage eol to point to the first whitespace
* after the last non-whitespace character before
* the end of the line */
for (; eol > uri && isspace(eol[-1]); eol--);
while (eol > uri && isspace((unsigned char)eol[-1]))
--eol;
/* now then, inspect the URI */
if (memcmp(val, "file", 4U) == 0) {
@ -727,7 +733,7 @@ _warc_rdlen(const char *buf, size_t bsz)
/* strtol kindly overreads whitespace for us, so use that */
val += sizeof(_key) - 1U;
len = strtol(val, &on, 10);
if (on == NULL || !isspace(*on)) {
if (on == NULL || !isspace((unsigned char)*on)) {
/* hm, can we trust that number? Best not. */
return -1;
}
@ -750,7 +756,7 @@ _warc_rdrtm(const char *buf, size_t bsz)
/* xstrpisotime() kindly overreads whitespace for us, so use that */
val += sizeof(_key) - 1U;
res = xstrpisotime(val, &on);
if (on == NULL || !isspace(*on)) {
if (on == NULL || !isspace((unsigned char)*on)) {
/* hm, can we trust that number? Best not. */
return (time_t)-1;
}
@ -773,7 +779,7 @@ _warc_rdmtm(const char *buf, size_t bsz)
/* xstrpisotime() kindly overreads whitespace for us, so use that */
val += sizeof(_key) - 1U;
res = xstrpisotime(val, &on);
if (on == NULL || !isspace(*on)) {
if (on == NULL || !isspace((unsigned char)*on)) {
/* hm, can we trust that number? Best not. */
return (time_t)-1;
}

View File

@ -181,6 +181,14 @@ struct zip {
char init_decryption;
/* Decryption buffer. */
/*
* The decrypted data starts at decrypted_ptr and
* extends for decrypted_bytes_remaining. Decryption
* adds new data to the end of this block, data is returned
* to clients from the beginning. When the block hits the
* end of decrypted_buffer, it has to be shuffled back to
* the beginning of the buffer.
*/
unsigned char *decrypted_buffer;
unsigned char *decrypted_ptr;
size_t decrypted_buffer_size;
@ -1293,8 +1301,9 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
if (zip->tctx_valid || zip->cctx_valid) {
if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) {
size_t buff_remaining = zip->decrypted_buffer_size
- (zip->decrypted_ptr - zip->decrypted_buffer);
size_t buff_remaining =
(zip->decrypted_buffer + zip->decrypted_buffer_size)
- (zip->decrypted_ptr + zip->decrypted_bytes_remaining);
if (buff_remaining > (size_t)bytes_avail)
buff_remaining = (size_t)bytes_avail;

View File

@ -43,6 +43,7 @@
.Nm archive_write_add_filter_program ,
.Nm archive_write_add_filter_uuencode ,
.Nm archive_write_add_filter_xz
.Nd functions enabling output filters
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS

View File

@ -467,7 +467,7 @@ archive_write_gnutar_header(struct archive_write *a,
}
}
if (gnutar->linkname_length > GNUTAR_linkname_size) {
size_t todo = gnutar->linkname_length;
size_t length = gnutar->linkname_length + 1;
struct archive_entry *temp = archive_entry_new2(&a->archive);
/* Uname/gname here don't really matter since no one reads them;
@ -476,7 +476,7 @@ archive_write_gnutar_header(struct archive_write *a,
archive_entry_set_gname(temp, "wheel");
archive_entry_set_pathname(temp, "././@LongLink");
archive_entry_set_size(temp, gnutar->linkname_length + 1);
archive_entry_set_size(temp, length);
ret = archive_format_gnutar_header(a, buff, temp, 'K');
if (ret < ARCHIVE_WARN)
goto exit_write_header;
@ -484,11 +484,12 @@ archive_write_gnutar_header(struct archive_write *a,
if(ret < ARCHIVE_WARN)
goto exit_write_header;
archive_entry_free(temp);
/* Write as many 512 bytes blocks as needed to write full name. */
ret = __archive_write_output(a, gnutar->linkname, todo);
/* Write name and trailing null byte. */
ret = __archive_write_output(a, gnutar->linkname, length);
if(ret < ARCHIVE_WARN)
goto exit_write_header;
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
/* Pad to 512 bytes */
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
if (ret < ARCHIVE_WARN)
goto exit_write_header;
}
@ -496,7 +497,7 @@ archive_write_gnutar_header(struct archive_write *a,
/* If pathname is longer than 100 chars we need to add an 'L' header. */
if (gnutar->pathname_length > GNUTAR_name_size) {
const char *pathname = gnutar->pathname;
size_t todo = gnutar->pathname_length;
size_t length = gnutar->pathname_length + 1;
struct archive_entry *temp = archive_entry_new2(&a->archive);
/* Uname/gname here don't really matter since no one reads them;
@ -505,7 +506,7 @@ archive_write_gnutar_header(struct archive_write *a,
archive_entry_set_gname(temp, "wheel");
archive_entry_set_pathname(temp, "././@LongLink");
archive_entry_set_size(temp, gnutar->pathname_length + 1);
archive_entry_set_size(temp, length);
ret = archive_format_gnutar_header(a, buff, temp, 'L');
if (ret < ARCHIVE_WARN)
goto exit_write_header;
@ -513,11 +514,12 @@ archive_write_gnutar_header(struct archive_write *a,
if(ret < ARCHIVE_WARN)
goto exit_write_header;
archive_entry_free(temp);
/* Write as many 512 bytes blocks as needed to write full name. */
ret = __archive_write_output(a, pathname, todo);
/* Write pathname + trailing null byte. */
ret = __archive_write_output(a, pathname, length);
if(ret < ARCHIVE_WARN)
goto exit_write_header;
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
/* Pad to multiple of 512 bytes. */
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
if (ret < ARCHIVE_WARN)
goto exit_write_header;
}

View File

@ -6225,7 +6225,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
unsigned char *p;
size_t l;
int r;
int ffmax, parent_len;
size_t ffmax, parent_len;
static const struct archive_rb_tree_ops rb_ops = {
isoent_cmp_node_joliet, isoent_cmp_key_joliet
};
@ -6239,7 +6239,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
else
ffmax = 128;
r = idr_start(a, idr, isoent->children.cnt, ffmax, 6, 2, &rb_ops);
r = idr_start(a, idr, isoent->children.cnt, (int)ffmax, 6, 2, &rb_ops);
if (r < 0)
return (r);
@ -6252,7 +6252,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
int ext_off, noff, weight;
size_t lt;
if ((int)(l = np->file->basename_utf16.length) > ffmax)
if ((l = np->file->basename_utf16.length) > ffmax)
l = ffmax;
p = malloc((l+1)*2);
@ -6285,7 +6285,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
/*
* Get a length of MBS of a full-pathname.
*/
if ((int)np->file->basename_utf16.length > ffmax) {
if (np->file->basename_utf16.length > ffmax) {
if (archive_strncpy_l(&iso9660->mbs,
(const char *)np->identifier, l,
iso9660->sconv_from_utf16be) != 0 &&
@ -6302,7 +6302,9 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
/* If a length of full-pathname is longer than 240 bytes,
* it violates Joliet extensions regulation. */
if (parent_len + np->mb_len > 240) {
if (parent_len > 240
|| np->mb_len > 240
|| parent_len + np->mb_len > 240) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"The regulation of Joliet extensions;"
" A length of a full-pathname of `%s' is "
@ -6314,11 +6316,11 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
/* Make an offset of the number which is used to be set
* hexadecimal number to avoid duplicate identifier. */
if ((int)l == ffmax)
if (l == ffmax)
noff = ext_off - 6;
else if ((int)l == ffmax-2)
else if (l == ffmax-2)
noff = ext_off - 4;
else if ((int)l == ffmax-4)
else if (l == ffmax-4)
noff = ext_off - 2;
else
noff = ext_off;

View File

@ -32,7 +32,7 @@
.Nm archive_write_set_format_option ,
.Nm archive_write_set_option ,
.Nm archive_write_set_options
.Nd functions controlling options for reading archives
.Nd functions controlling options for writing archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS

View File

@ -65,7 +65,6 @@ Later variants have extended this by either appropriating undefined
areas of the header record, extending the header to multiple records,
or by storing special entries that modify the interpretation of
subsequent entries.
.Pp
.Bl -tag -width indent
.It Cm gnutar
The

View File

@ -28,7 +28,7 @@
.Dt LIBARCHIVE_CHANGES 3
.Os
.Sh NAME
.Nm changes in libarchive interface
.Nd changes in libarchive interface
.\"
.Sh CHANGES IN LIBARCHIVE 3
This page describes user-visible changes in libarchive3, and lists

View File

@ -2533,18 +2533,36 @@ usage(const char *program)
static char *
get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
size_t tried_size, buff_size;
char *buff, *tried, *pwd = NULL, *p = NULL;
#ifdef PATH_MAX
buff_size = PATH_MAX;
#else
buff_size = 8192;
#endif
buff = calloc(buff_size, 1);
if (buff == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* Allocate a buffer to hold the various directories we checked. */
tried_size = buff_size * 2;
tried = calloc(tried_size, 1);
if (tried == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* If a dir was specified, try that */
if (d != NULL) {
pwd = NULL;
snprintf(buff, sizeof(buff), "%s", d);
snprintf(buff, buff_size, "%s", d);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
goto failure;
}
@ -2558,48 +2576,48 @@ get_refdir(const char *d)
pwd[strlen(pwd) - 1] = '\0';
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
snprintf(buff, buff_size, "%s", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd);
snprintf(buff, buff_size, "%s/test", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(PROGRAM_ALIAS)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#endif
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
snprintf(buff, buff_size, "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
snprintf(buff, buff_size, "%s/test", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
}
failure:
@ -2614,7 +2632,12 @@ get_refdir(const char *d)
success:
free(p);
free(pwd);
return strdup(buff);
free(tried);
/* Copy result into a fresh buffer to reduce memory usage. */
p = strdup(buff);
free(buff);
return p;
}
int

View File

@ -0,0 +1,44 @@
/*-
* Copyright (c) 2003-2016 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
__FBSDID("$FreeBSD$");
DEFINE_TEST(test_read_format_rar_invalid1)
{
const char *refname = "test_read_format_rar_invalid1.rar";
struct archive *a;
struct archive_entry *ae;
char *buff[100];
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buff, 99));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,5 @@
begin 644 test_read_format_rar_invalid1.rar
M4F%R(1H'`,^0<P``#0````````"9SG0@D"8`#`````,````#+7,'\(^>B$4=
2,P0`I($``'1E<W0`P/\````)
`
end

View File

@ -0,0 +1,145 @@
/*-
* Copyright (c) 2016 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
__FBSDID("$FreeBSD$");
/*
* Inspired by Github issue #682, which reported that gnutar filenames
* of exactly 512 bytes weren't getting written correctly.
*
* This writes a filename of every length from 1 to 2000 bytes and
* reads back to verify it.
*/
static char filename[2048];
DEFINE_TEST(test_write_format_gnutar_filenames)
{
size_t buffsize = 1000000;
char *buff;
struct archive_entry *ae, *template;
struct archive *a;
size_t used;
buff = malloc(buffsize); /* million bytes of work area */
assert(buff != NULL);
/* Create a template entry. */
assert((template = archive_entry_new()) != NULL);
archive_entry_set_atime(template, 2, 20);
archive_entry_set_birthtime(template, 3, 30);
archive_entry_set_ctime(template, 4, 40);
archive_entry_set_mtime(template, 5, 50);
archive_entry_set_mode(template, S_IFREG | 0755);
archive_entry_set_size(template, 8);
for (int i = 0; i < 2000; ++i) {
filename[i] = 'a';
filename[i + 1] = '\0';
archive_entry_copy_pathname(template, filename);
/* Write a one-item gnutar format archive. */
assert((a = archive_write_new()) != NULL);
assertA(0 == archive_write_set_format_gnutar(a));
assertA(0 == archive_write_add_filter_none(a));
assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, template));
assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
/* Read back and verify the filename. */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, 0, archive_read_support_format_all(a));
assertEqualIntA(a, 0, archive_read_support_filter_all(a));
assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertEqualString(filename, archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
archive_entry_free(template);
free(buff);
}
DEFINE_TEST(test_write_format_gnutar_linknames)
{
size_t buffsize = 1000000;
char *buff;
struct archive_entry *ae, *template;
struct archive *a;
size_t used;
buff = malloc(buffsize); /* million bytes of work area */
assert(buff != NULL);
/* Create a template entry. */
assert((template = archive_entry_new()) != NULL);
archive_entry_set_atime(template, 2, 20);
archive_entry_set_birthtime(template, 3, 30);
archive_entry_set_ctime(template, 4, 40);
archive_entry_set_mtime(template, 5, 50);
archive_entry_set_mode(template, S_IFLNK | 0755);
archive_entry_copy_pathname(template, "link");
for (int i = 0; i < 2000; ++i) {
filename[i] = 'a';
filename[i + 1] = '\0';
archive_entry_copy_symlink(template, filename);
/* Write a one-item gnutar format archive. */
assert((a = archive_write_new()) != NULL);
assertA(0 == archive_write_set_format_gnutar(a));
assertA(0 == archive_write_add_filter_none(a));
assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, template));
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
/* Read back and verify the filename. */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, 0, archive_read_support_format_all(a));
assertEqualIntA(a, 0, archive_read_support_filter_all(a));
assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertEqualString("link", archive_entry_pathname(ae));
assertEqualString(filename, archive_entry_symlink(ae));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
archive_entry_free(template);
free(buff);
}

View File

@ -121,14 +121,15 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
#else /* _WIN32 && !__CYGWIN__ */
#include <termios.h>
#include <signal.h>
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <signal.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#ifdef TCSASOFT
@ -142,11 +143,18 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
# define _POSIX_VDISABLE VDISABLE
#endif
static volatile sig_atomic_t *signo;
#define M(a,b) (a > b ? a : b)
#define MAX_SIGNO M(M(M(SIGALRM, SIGHUP), \
M(SIGINT, SIGPIPE)), \
M(M(SIGQUIT, SIGTERM), \
M(M(SIGTSTP, SIGTTIN), SIGTTOU)))
static volatile sig_atomic_t signo[MAX_SIGNO + 1];
static void
handler(int s)
{
assert(s <= MAX_SIGNO);
signo[s] = 1;
}
@ -166,12 +174,8 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
return(NULL);
}
if (signo == NULL) {
signo = calloc(SIGRTMAX, sizeof(sig_atomic_t));
}
restart:
for (i = 0; i < SIGRTMAX; i++)
for (i = 0; i <= MAX_SIGNO; i++)
signo[i] = 0;
nr = -1;
save_errno = 0;
@ -198,6 +202,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0; /* don't restart system calls */
sa.sa_handler = handler;
/* Keep this list in sync with MAX_SIGNO! */
(void)sigaction(SIGALRM, &sa, &savealrm);
(void)sigaction(SIGHUP, &sa, &savehup);
(void)sigaction(SIGINT, &sa, &saveint);
@ -237,11 +242,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
if (p < end) {
if ((flags & RPP_SEVENBIT))
ch &= 0x7f;
if (isalpha(ch)) {
if (isalpha((unsigned char)ch)) {
if ((flags & RPP_FORCELOWER))
ch = (char)tolower(ch);
ch = (char)tolower((unsigned char)ch);
if ((flags & RPP_FORCEUPPER))
ch = (char)toupper(ch);
ch = (char)toupper((unsigned char)ch);
}
*p++ = ch;
}
@ -276,7 +281,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
* If we were interrupted by a signal, resend it to ourselves
* now that we have restored the signal handlers.
*/
for (i = 0; i < SIGRTMAX; i++) {
for (i = 0; i <= MAX_SIGNO; i++) {
if (signo[i]) {
kill(getpid(), i);
switch (i) {

View File

@ -2535,18 +2535,36 @@ usage(const char *program)
static char *
get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
size_t tried_size, buff_size;
char *buff, *tried, *pwd = NULL, *p = NULL;
#ifdef PATH_MAX
buff_size = PATH_MAX;
#else
buff_size = 8192;
#endif
buff = calloc(buff_size, 1);
if (buff == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* Allocate a buffer to hold the various directories we checked. */
tried_size = buff_size * 2;
tried = calloc(tried_size, 1);
if (tried == NULL) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
/* If a dir was specified, try that */
if (d != NULL) {
pwd = NULL;
snprintf(buff, sizeof(buff), "%s", d);
snprintf(buff, buff_size, "%s", d);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
goto failure;
}
@ -2560,48 +2578,48 @@ get_refdir(const char *d)
pwd[strlen(pwd) - 1] = '\0';
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
snprintf(buff, buff_size, "%s", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd);
snprintf(buff, buff_size, "%s/test", pwd);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
#else
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#if defined(PROGRAM_ALIAS)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
#endif
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
snprintf(buff, buff_size, "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
snprintf(buff, sizeof(buff), "%s/test", pwd + 8);
snprintf(buff, buff_size, "%s/test", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
strncat(tried, buff, tried_size - strlen(tried) - 1);
strncat(tried, "\n", tried_size - strlen(tried) - 1);
}
failure:
@ -2616,7 +2634,12 @@ get_refdir(const char *d)
success:
free(p);
free(pwd);
return strdup(buff);
free(tried);
/* Copy result into a fresh buffer to reduce memory usage. */
p = strdup(buff);
free(buff);
return p;
}
int

View File

@ -0,0 +1,37 @@
/*-
* Copyright (c) 2016 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
__FBSDID("$FreeBSD$");
DEFINE_TEST(test_missing_file)
{
assertMakeFile("file1", 0644, "file1");
assertMakeFile("file2", 0644, "file2");
assert(0 == systemf("%s -cf archive.tar file1 file2 2>stderr1", testprog));
assertEmptyFile("stderr1");
assert(0 != systemf("%s -cf archive.tar file1 file2 file3 2>stderr2", testprog));
assert(0 != systemf("%s -cf archive.tar 2>stderr3", testprog));
assert(0 != systemf("%s -cf archive.tar file3 2>stderr4", testprog));
}

View File

@ -884,7 +884,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
else if (r != ARCHIVE_OK) {
lafe_warnc(archive_errno(disk),
"%s", archive_error_string(disk));
if (r == ARCHIVE_FATAL) {
if (r == ARCHIVE_FATAL || r == ARCHIVE_FAILED) {
bsdtar->return_value = 1;
return;
} else if (r < ARCHIVE_WARN)

View File

@ -154,6 +154,7 @@ TESTS_SRCS= \
test_read_format_rar_encryption_data.c \
test_read_format_rar_encryption_header.c \
test_read_format_rar_encryption_partially.c \
test_read_format_rar_invalid1.c \
test_read_format_raw.c \
test_read_format_tar.c \
test_read_format_tar_concatenated.c \
@ -233,6 +234,7 @@ TESTS_SRCS= \
test_write_format_cpio_newc.c \
test_write_format_cpio_odc.c \
test_write_format_gnutar.c \
test_write_format_gnutar_filenames.c \
test_write_format_iso9660.c \
test_write_format_iso9660_boot.c \
test_write_format_iso9660_empty.c \
@ -468,6 +470,7 @@ ${PACKAGE}FILES+= test_read_format_rar_compress_normal.rar.uu
${PACKAGE}FILES+= test_read_format_rar_encryption_data.rar.uu
${PACKAGE}FILES+= test_read_format_rar_encryption_header.rar.uu
${PACKAGE}FILES+= test_read_format_rar_encryption_partially.rar.uu
${PACKAGE}FILES+= test_read_format_rar_invalid1.rar.uu
${PACKAGE}FILES+= test_read_format_rar_multi_lzss_blocks.rar.uu
${PACKAGE}FILES+= test_read_format_rar_multivolume.part0001.rar.uu
${PACKAGE}FILES+= test_read_format_rar_multivolume.part0002.rar.uu

View File

@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive
_LIBARCHIVECONFDIR= ${.CURDIR}/../../lib/libarchive
PROG= bsdcat
BSDCAT_VERSION_STRING= 3.2.0
BSDCAT_VERSION_STRING= 3.2.1
.PATH: ${_LIBARCHIVEDIR}/cat
SRCS= bsdcat.c cmdline.c

View File

@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive
_LIBARCHIVECONFDIR= ${.CURDIR}/../../lib/libarchive
PROG= bsdcpio
BSDCPIO_VERSION_STRING= 3.2.0
BSDCPIO_VERSION_STRING= 3.2.1
.PATH: ${_LIBARCHIVEDIR}/cpio
SRCS= cpio.c cmdline.c

View File

@ -44,6 +44,7 @@ TESTS_SRCS= \
test_extract_cpio_xz.c \
test_format_newc.c \
test_gcpio_compat.c \
test_missing_file.c \
test_option_0.c \
test_option_B_upper.c \
test_option_C_upper.c \

View File

@ -4,7 +4,7 @@
_LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive
PROG= bsdtar
BSDTAR_VERSION_STRING= 3.2.0
BSDTAR_VERSION_STRING= 3.2.1
.PATH: ${_LIBARCHIVEDIR}/tar
SRCS= bsdtar.c \

View File

@ -37,6 +37,7 @@ TESTS_SRCS= \
test_format_newc.c \
test_help.c \
test_leading_slash.c \
test_missing_file.c \
test_option_C_upper.c \
test_option_H_upper.c \
test_option_L_upper.c \