libarchive-clib 3.8.5 → 3.8.6
raw patch · 19 files changed
+199/−53 lines, 19 files
Files
- c/archive.h +2/−2
- c/archive_acl.c +5/−1
- c/archive_cryptor_private.h +4/−0
- c/archive_entry.h +1/−1
- c/archive_hmac.c +6/−0
- c/archive_read_open_filename.c +4/−3
- c/archive_read_support_filter_program.c +2/−0
- c/archive_read_support_format_7zip.c +11/−3
- c/archive_read_support_format_cab.c +3/−1
- c/archive_read_support_format_lha.c +7/−0
- c/archive_read_support_format_mtree.c +6/−1
- c/archive_read_support_format_rar5.c +20/−7
- c/archive_string.c +12/−2
- c/archive_write_disk_posix.c +15/−7
- c/archive_write_set_format_gnutar.c +29/−5
- c/archive_write_set_format_ustar.c +20/−7
- c/archive_write_set_format_v7tar.c +22/−5
- c/archive_write_set_format_zip.c +29/−7
- libarchive-clib.cabal +1/−1
c/archive.h view
@@ -34,7 +34,7 @@ * assert that ARCHIVE_VERSION_NUMBER >= 2012108. */ /* Note: Compiler will complain if this does not match archive_entry.h! */-#define ARCHIVE_VERSION_NUMBER 3008005+#define ARCHIVE_VERSION_NUMBER 3008006 #include <sys/stat.h> #include <stddef.h> /* for wchar_t */@@ -177,7 +177,7 @@ /* * Textual name/version of the library, useful for version displays. */-#define ARCHIVE_VERSION_ONLY_STRING "3.8.5"+#define ARCHIVE_VERSION_ONLY_STRING "3.8.6" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void);
c/archive_acl.c view
@@ -1256,8 +1256,12 @@ tag = 0; s = field[n].start;- st = field[n].start + 1; len = field[n].end - field[n].start;+ if (len == 0) {+ ret = ARCHIVE_WARN;+ continue;+ }+ st = s + 1; switch (*s) { case L'u':
c/archive_cryptor_private.h view
@@ -109,6 +109,10 @@ #include <nettle/version.h> #define ARCHIVE_CRYPTOR_USE_NETTLE 1 +#ifndef AES_MAX_KEY_SIZE+#define AES_MAX_KEY_SIZE AES256_KEY_SIZE+#endif+ typedef struct { #if NETTLE_VERSION_MAJOR < 3 struct aes_ctx ctx;
c/archive_entry.h view
@@ -28,7 +28,7 @@ #define ARCHIVE_ENTRY_H_INCLUDED /* Note: Compiler will complain if this does not match archive.h! */-#define ARCHIVE_VERSION_NUMBER 3008005+#define ARCHIVE_VERSION_NUMBER 3008006 /* * Note: archive_entry.h is for use outside of libarchive; the
c/archive_hmac.c view
@@ -198,6 +198,7 @@ } #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)+#include <nettle/version.h> static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)@@ -216,7 +217,12 @@ static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) {+#if NETTLE_VERSION_MAJOR < 4 hmac_sha1_digest(ctx, (unsigned)*out_len, out);+#else+ hmac_sha1_digest(ctx, out);+ *out_len = SHA1_DIGEST_SIZE;+#endif } static void
c/archive_read_open_filename.c view
@@ -122,13 +122,14 @@ archive_clear_error(a); do {+ size_t len; if (filename == NULL) filename = "";- mine = calloc(1,- sizeof(*mine) + strlen(filename));+ len = strlen(filename);+ mine = calloc(1, sizeof(*mine) + len); if (mine == NULL) goto no_memory;- strcpy(mine->filename.m, filename);+ memcpy(mine->filename.m, filename, len + 1); mine->block_size = block_size; mine->fd = -1; mine->buffer = NULL;
c/archive_read_support_filter_program.c view
@@ -149,6 +149,8 @@ if (signature != NULL && signature_len > 0) { state->signature_len = signature_len; state->signature = malloc(signature_len);+ if (state->signature == NULL)+ goto memerr; memcpy(state->signature, signature, signature_len); }
c/archive_read_support_format_7zip.c view
@@ -34,6 +34,9 @@ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif+#ifdef HAVE_LIMITS_H+#include <limits.h>+#endif #ifdef HAVE_BZLIB_H #include <bzlib.h> #endif@@ -80,7 +83,7 @@ /* * ELF format */-#define ELF_HDR_MIN_LEN 0x3f+#define ELF_HDR_MIN_LEN 0x40 /* sizeof(Elf64_Ehdr) */ #define ELF_HDR_EI_CLASS_OFFSET 0x04 #define ELF_HDR_EI_DATA_OFFSET 0x05 @@ -855,13 +858,18 @@ while (e_shnum > 0) { name_offset = (*dec32)(h + sec_tbl_offset); if (name_offset == data_sym_offset) {+ uint64_t sel_offset;+ if (format_64) {- min_addr = (*dec64)(+ sel_offset = (*dec64)( h + sec_tbl_offset + 0x18); } else {- min_addr = (*dec32)(+ sel_offset = (*dec32)( h + sec_tbl_offset + 0x10); }+ if (sel_offset > SSIZE_MAX)+ break;+ min_addr = (ssize_t)sel_offset; break; } sec_tbl_offset += e_shentsize;
c/archive_read_support_format_cab.c view
@@ -383,8 +383,10 @@ NULL, NULL); - if (r != ARCHIVE_OK)+ if (r != ARCHIVE_OK) {+ archive_wstring_free(&cab->ws); free(cab);+ } return (ARCHIVE_OK); }
c/archive_read_support_format_lha.c view
@@ -1101,6 +1101,13 @@ header_crc = lha_crc16(0, p, H3_FIXED_SIZE); __archive_read_consume(a, H3_FIXED_SIZE); + /* Reject rediculously large header */+ if (lha->header_size > 65536) {+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,+ "LHa header size too large");+ return (ARCHIVE_FATAL);+ }+ /* Read extended headers */ err = lha_read_file_extended_header(a, lha, &header_crc, 4, lha->header_size - H3_FIXED_SIZE, &extdsize);
c/archive_read_support_format_mtree.c view
@@ -300,7 +300,12 @@ struct mtree_entry *p, *q; mtree = (struct mtree *)(a->format->data);-+ + /* Close any dangling file descriptor before freeing */+ if (mtree->fd >= 0) {+ close(mtree->fd);+ mtree->fd = -1;+ } p = mtree->entries; while (p != NULL) { q = p->next;
c/archive_read_support_format_rar5.c view
@@ -375,6 +375,7 @@ static int push_data_ready(struct archive_read* a, struct rar5* rar, const uint8_t* buf, size_t size, int64_t offset); static void clear_data_ready_stack(struct rar5* rar);+static void rar5_deinit(struct rar5* rar); /* CDE_xxx = Circular Double Ended (Queue) return values. */ enum CDE_RETURN_VALUES {@@ -429,8 +430,7 @@ return CDE_OUT_OF_BOUNDS; } -/* Pushes a new element into the end of this circular deque object. If current- * size will exceed capacity, the oldest element will be overwritten. */+/* Pushes a new element into the end of this circular deque object. */ static int cdeque_push_back(struct cdeque* d, void* item) { if(d == NULL) return CDE_PARAM;@@ -554,7 +554,11 @@ return NULL; } - cdeque_push_back(&rar->cstate.filters, cdeque_filter(f));+ if (CDE_OK != cdeque_push_back(&rar->cstate.filters, cdeque_filter(f))) {+ free(f);+ return NULL;+ }+ return f; } @@ -3040,7 +3044,9 @@ if(block_length < 4 || block_length > 0x400000 || filter_type > FILTER_ARM ||- !is_valid_filter_block_start(rar, block_start))+ !is_valid_filter_block_start(rar, block_start) ||+ (rar->cstate.window_size > 0 &&+ (ssize_t)block_length > rar->cstate.window_size >> 1)) { archive_set_error(&ar->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Invalid filter encountered");@@ -4328,7 +4334,7 @@ free(rar->vol.push_buf); free_filters(rar);- cdeque_free(&rar->cstate.filters);+ rar5_deinit(rar); free(rar); a->format->data = NULL;@@ -4353,6 +4359,7 @@ return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; } +/* Must match deallocations in rar5_deinit */ static int rar5_init(struct rar5* rar) { memset(rar, 0, sizeof(struct rar5)); @@ -4368,6 +4375,11 @@ return ARCHIVE_OK; } +/* Must match allocations in rar5_init */+static void rar5_deinit(struct rar5* rar) {+ cdeque_free(&rar->cstate.filters);+}+ int archive_read_support_format_rar5(struct archive *_a) { struct archive_read* ar; int ret;@@ -4404,8 +4416,9 @@ rar5_has_encrypted_entries); if(ret != ARCHIVE_OK) {- (void) rar5_cleanup(ar);+ rar5_deinit(rar);+ free(rar); } - return ret;+ return ARCHIVE_OK; }
c/archive_string.c view
@@ -772,7 +772,7 @@ int r; defchar_used = 0;- if (to_cp == CP_UTF8 || sc == NULL)+ if (to_cp == CP_UTF8) dp = NULL; else dp = &defchar_used;@@ -1873,6 +1873,9 @@ const char * archive_string_conversion_charset_name(struct archive_string_conv *sc) {+ if (sc == NULL) {+ return "current locale";+ } if (sc->flag & SCONV_TO_CHARSET) return (sc->to_charset); else@@ -4123,7 +4126,12 @@ * character-set. */ if ((aes->aes_set & AES_SET_MBS) == 0) { const char *pm; /* unused */- archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */+ if (archive_mstring_get_mbs(a, aes, &pm) != 0) {+ /* We have another form, but failed to convert it to+ * the native locale. Transitively, we've failed to+ * convert it to the specified character set. */+ ret = -1;+ } } /* If we already have an MBS form, use it to be translated to * specified character-set. */@@ -4141,6 +4149,8 @@ if (length != NULL) *length = aes->aes_mbs_in_locale.length; } else {+ /* Either we have no string in any form,+ * or conversion failed and set 'ret != 0'. */ *p = NULL; if (length != NULL) *length = 0;
c/archive_write_disk_posix.c view
@@ -1975,7 +1975,7 @@ return (a->lookup_gid)(a->lookup_gid_data, name, id); return (id); }- + int64_t archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id) {@@ -2406,7 +2406,7 @@ */ mode = final_mode & 0777 & ~a->user_umask; - /* + /* * Always create writable such that [f]setxattr() works if we're not * root. */@@ -3024,7 +3024,7 @@ /* * We are not the last element and we want to * follow symlinks if they are a directory.- * + * * This is needed to extract hardlinks over * symlinks. */@@ -3435,7 +3435,7 @@ le = new_fixup(a, path); if (le == NULL) return (ARCHIVE_FATAL);- le->fixup |=TODO_MODE_BASE;+ le->fixup |= TODO_MODE_BASE; le->mode = mode_final; } return (ARCHIVE_OK);@@ -3447,8 +3447,17 @@ * don't add it to the fixup list here, as it's already been * added. */- if (la_stat(path, &st) == 0 && S_ISDIR(st.st_mode))- return (ARCHIVE_OK);+ if (errno == EEXIST) {+ if (la_stat(path, &st) == 0) {+ if (S_ISDIR(st.st_mode))+ return (ARCHIVE_OK);+ /* path exists but is not a directory */+ errno = ENOTDIR;+ } else {+ /* restore original errno */+ errno = EEXIST;+ }+ } archive_set_error(&a->archive, errno, "Failed to create dir '%s'", path);@@ -4767,4 +4776,3 @@ #endif /* !_WIN32 || __CYGWIN__ */-
c/archive_write_set_format_gnutar.c view
@@ -293,6 +293,17 @@ } else sconv = gnutar->opt_sconv; + /* Sanity check. */+ if (archive_entry_pathname(entry) == NULL+#if defined(_WIN32) && !defined(__CYGWIN__)+ && archive_entry_pathname_w(entry) == NULL+#endif+ ) {+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,+ "Can't record entry in tar file without pathname");+ return ARCHIVE_FAILED;+ }+ /* Only regular files (not hardlinks) have data. */ if (archive_entry_hardlink(entry) != NULL || archive_entry_symlink(entry) != NULL ||@@ -385,17 +396,30 @@ r = archive_entry_pathname_l(entry, &(gnutar->pathname), &(gnutar->pathname_length), sconv); if (r != 0) {+ const char* p_mbs; if (errno == ENOMEM) { archive_set_error(&a->archive, ENOMEM, "Can't allocate memory for pathname"); ret = ARCHIVE_FATAL; goto exit_write_header; }- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,- "Can't translate pathname '%s' to %s",- archive_entry_pathname(entry),- archive_string_conversion_charset_name(sconv));- ret2 = ARCHIVE_WARN;+ p_mbs = archive_entry_pathname(entry);+ if (p_mbs) {+ /* We have a wrongly-encoded MBS pathname.+ * Warn and use it. */+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_FILE_FORMAT,+ "Can't translate pathname '%s' to %s", p_mbs,+ archive_string_conversion_charset_name(sconv));+ ret2 = ARCHIVE_WARN;+ } else {+ /* We have no MBS pathname. Fail. */+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_FILE_FORMAT,+ "Can't translate pathname to %s",+ archive_string_conversion_charset_name(sconv));+ return ARCHIVE_FAILED;+ } } r = archive_entry_uname_l(entry, &(gnutar->uname), &(gnutar->uname_length), sconv);
c/archive_write_set_format_ustar.c view
@@ -254,11 +254,11 @@ sconv = ustar->opt_sconv; /* Sanity check. */+ if (archive_entry_pathname(entry) == NULL #if defined(_WIN32) && !defined(__CYGWIN__)- if (archive_entry_pathname_w(entry) == NULL) {-#else- if (archive_entry_pathname(entry) == NULL) {+ && archive_entry_pathname_w(entry) == NULL #endif+ ) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Can't record entry in tar file without pathname"); return (ARCHIVE_FAILED);@@ -409,15 +409,28 @@ */ r = archive_entry_pathname_l(entry, &pp, ©_length, sconv); if (r != 0) {+ const char* p_mbs; if (errno == ENOMEM) { archive_set_error(&a->archive, ENOMEM, "Can't allocate memory for Pathname"); return (ARCHIVE_FATAL); }- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,- "Can't translate pathname '%s' to %s",- pp, archive_string_conversion_charset_name(sconv));- ret = ARCHIVE_WARN;+ p_mbs = archive_entry_pathname(entry);+ if (p_mbs) {+ /* We have a wrongly-encoded MBS pathname.+ * Warn and use it. */+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,+ "Can't translate pathname '%s' to %s", p_mbs,+ archive_string_conversion_charset_name(sconv));+ ret = ARCHIVE_WARN;+ } else {+ /* We have no MBS pathname. Fail. */+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_FILE_FORMAT,+ "Can't translate pathname to %s",+ archive_string_conversion_charset_name(sconv));+ return ARCHIVE_FAILED;+ } } if (copy_length <= USTAR_name_size) memcpy(h + USTAR_name_offset, pp, copy_length);
c/archive_write_set_format_v7tar.c view
@@ -232,7 +232,11 @@ sconv = v7tar->opt_sconv; /* Sanity check. */- if (archive_entry_pathname(entry) == NULL) {+ if (archive_entry_pathname(entry) == NULL+#if defined(_WIN32) && !defined(__CYGWIN__)+ && archive_entry_pathname_w(entry) == NULL+#endif+ ) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Can't record entry in tar file without pathname"); return (ARCHIVE_FAILED);@@ -382,15 +386,28 @@ */ r = archive_entry_pathname_l(entry, &pp, ©_length, sconv); if (r != 0) {+ const char* p_mbs; if (errno == ENOMEM) { archive_set_error(&a->archive, ENOMEM, "Can't allocate memory for Pathname"); return (ARCHIVE_FATAL); }- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,- "Can't translate pathname '%s' to %s",- pp, archive_string_conversion_charset_name(sconv));- ret = ARCHIVE_WARN;+ p_mbs = archive_entry_pathname(entry);+ if (p_mbs) {+ /* We have a wrongly-encoded MBS pathname.+ * Warn and use it. */+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,+ "Can't translate pathname '%s' to %s", p_mbs,+ archive_string_conversion_charset_name(sconv));+ ret = ARCHIVE_WARN;+ } else {+ /* We have no MBS pathname. Fail. */+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_FILE_FORMAT,+ "Can't translate pathname to %s",+ archive_string_conversion_charset_name(sconv));+ return ARCHIVE_FAILED;+ } } if (strict && copy_length < V7TAR_name_size) memcpy(h + V7TAR_name_offset, pp, copy_length);
c/archive_write_set_format_zip.c view
@@ -802,6 +802,17 @@ int version_needed = 10; #define MIN_VERSION_NEEDED(x) do { if (version_needed < x) { version_needed = x; } } while (0) + /* Sanity check. */+ if (archive_entry_pathname(entry) == NULL+#if defined(_WIN32) && !defined(__CYGWIN__)+ && archive_entry_pathname_w(entry) == NULL+#endif+ ) {+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,+ "Can't record entry in zip file without pathname");+ return ARCHIVE_FAILED;+ }+ /* Ignore types of entries that we don't support. */ type = archive_entry_filetype(entry); if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {@@ -882,22 +893,33 @@ return (ARCHIVE_FATAL); } - if (sconv != NULL) {+ { const char *p; size_t len; if (archive_entry_pathname_l(zip->entry, &p, &len, sconv) != 0) {+ const char* p_mbs; if (errno == ENOMEM) { archive_set_error(&a->archive, ENOMEM, "Can't allocate memory for Pathname"); return (ARCHIVE_FATAL); }- archive_set_error(&a->archive,- ARCHIVE_ERRNO_FILE_FORMAT,- "Can't translate Pathname '%s' to %s",- archive_entry_pathname(zip->entry),- archive_string_conversion_charset_name(sconv));- ret2 = ARCHIVE_WARN;+ p_mbs = archive_entry_pathname(zip->entry);+ if (p_mbs) {+ /* We have a wrongly-encoded MBS pathname. Warn and use it. */+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_FILE_FORMAT,+ "Can't translate pathname '%s' to %s", p_mbs,+ archive_string_conversion_charset_name(sconv));+ ret2 = ARCHIVE_WARN;+ } else {+ /* We have no MBS pathname. Fail. */+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_FILE_FORMAT,+ "Can't translate pathname to %s",+ archive_string_conversion_charset_name(sconv));+ return ARCHIVE_FAILED;+ } } if (len > 0) archive_entry_set_pathname(zip->entry, p);
libarchive-clib.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: libarchive-clib-version: 3.8.5+version: 3.8.6 license: OtherLicense license-file: LICENSE copyright: Copyright: (c) 2018-2020 Vanessa McHale