summaryrefslogtreecommitdiff
path: root/libarchive
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@gmail.com>2010-03-01 00:36:29 -0500
committerTim Kientzle <kientzle@gmail.com>2010-03-01 00:36:29 -0500
commit42c1f3e1243e684bc003d857450496a274d16a31 (patch)
tree9cb18cff0a6a3f22efa65645d6f6d16f053d308e /libarchive
parent061edc88add6320353d46c385829e6e16b0e4e89 (diff)
downloadlibarchive-42c1f3e1243e684bc003d857450496a274d16a31.tar.gz
Open a door to changing the current abort-on-state-failure behavior:
* Change __archive_check_magic to return a status code. * Change callers to use the archive_check_magic() wrapper macro, which calls __archive_check_magic and returns immediately if there's an ARCHIVE_FATAL status. * Update a bunch of API calls to actually do magic state checks. I've also changed __archive_check_magic around a little bit: * Magic number checks still call abort(). * State failures still call abort() * Starting with libarchive 3.0, state failures will return ARCHIVE_FATAL. SVN-Revision: 2003
Diffstat (limited to 'libarchive')
-rw-r--r--libarchive/archive.h5
-rw-r--r--libarchive/archive_check_magic.c55
-rw-r--r--libarchive/archive_entry.h6
-rw-r--r--libarchive/archive_private.h13
-rw-r--r--libarchive/archive_read.c49
-rw-r--r--libarchive/archive_read_data_into_fd.c3
-rw-r--r--libarchive/archive_read_disk.c35
-rw-r--r--libarchive/archive_read_support_format_ar.c3
-rw-r--r--libarchive/archive_read_support_format_cpio.c3
-rw-r--r--libarchive/archive_read_support_format_empty.c3
-rw-r--r--libarchive/archive_read_support_format_iso9660.c3
-rw-r--r--libarchive/archive_read_support_format_mtree.c3
-rw-r--r--libarchive/archive_read_support_format_raw.c3
-rw-r--r--libarchive/archive_read_support_format_tar.c5
-rw-r--r--libarchive/archive_read_support_format_xar.c5
-rw-r--r--libarchive/archive_read_support_format_zip.c3
-rw-r--r--libarchive/archive_write.c63
-rw-r--r--libarchive/archive_write_add_filter_bzip2.c4
-rw-r--r--libarchive/archive_write_add_filter_compress.c4
-rw-r--r--libarchive/archive_write_add_filter_gzip.c4
-rw-r--r--libarchive/archive_write_add_filter_program.c4
-rw-r--r--libarchive/archive_write_add_filter_xz.c20
-rw-r--r--libarchive/archive_write_disk.c24
-rw-r--r--libarchive/archive_write_set_format_ar.c12
-rw-r--r--libarchive/archive_write_set_format_by_name.c1
-rw-r--r--libarchive/archive_write_set_format_cpio.c3
-rw-r--r--libarchive/archive_write_set_format_cpio_newc.c3
-rw-r--r--libarchive/archive_write_set_format_iso9660.c3
-rw-r--r--libarchive/archive_write_set_format_mtree.c3
-rw-r--r--libarchive/archive_write_set_format_pax.c7
-rw-r--r--libarchive/archive_write_set_format_shar.c3
-rw-r--r--libarchive/archive_write_set_format_ustar.c3
-rw-r--r--libarchive/archive_write_set_format_zip.c3
33 files changed, 241 insertions, 120 deletions
diff --git a/libarchive/archive.h b/libarchive/archive.h
index 5fcb688d..935a8a00 100644
--- a/libarchive/archive.h
+++ b/libarchive/archive.h
@@ -138,13 +138,14 @@ extern "C" {
* (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000)
* #endif
*/
-#define ARCHIVE_VERSION_NUMBER 3000000
+/* Note: Compiler will complain if this does not match archive_entry.h! */
+#define ARCHIVE_VERSION_NUMBER 2008900
__LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_STRING "libarchive 3.0.0a"
+#define ARCHIVE_VERSION_STRING "libarchive 2.8.900a"
__LA_DECL const char * archive_version_string(void);
#if ARCHIVE_VERSION_NUMBER < 3000000
diff --git a/libarchive/archive_check_magic.c b/libarchive/archive_check_magic.c
index e27e5d82..3b6888b8 100644
--- a/libarchive/archive_check_magic.c
+++ b/libarchive/archive_check_magic.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -87,48 +87,65 @@ state_name(unsigned s)
}
-static void
-write_all_states(unsigned int states)
+static char *
+write_all_states(char *buff, unsigned int states)
{
unsigned int lowbit;
+ buff[0] = '\0';
+
/* A trick for computing the lowest set bit. */
while ((lowbit = states & (1 + ~states)) != 0) {
states &= ~lowbit; /* Clear the low bit. */
- errmsg(state_name(lowbit));
+ strcat(buff, state_name(lowbit));
if (states != 0)
- errmsg("/");
+ strcat(buff, "/");
}
+ return buff;
}
/*
- * Check magic value and current state; bail if it isn't valid.
+ * Check magic value and current state.
+ * Magic value mismatches are fatal and result in calls to abort().
+ * State mismatches return ARCHIVE_FATAL.
+ * Otherwise, returns ARCHIVE_OK.
*
* This is designed to catch serious programming errors that violate
* the libarchive API.
*/
-void
+int
__archive_check_magic(struct archive *a, unsigned int magic,
unsigned int state, const char *function)
{
+ char states1[64];
+ char states2[64];
+
if (a->magic != magic) {
- errmsg("INTERNAL ERROR: Function ");
+ errmsg("PROGRAMMER ERROR: Function ");
errmsg(function);
- errmsg(" invoked with invalid struct archive structure.\n");
+ errmsg(" invoked with invalid archive handle.\n");
diediedie();
}
- if (state == ARCHIVE_STATE_ANY)
- return;
-
if ((a->state & state) == 0) {
- errmsg("INTERNAL ERROR: Function '");
- errmsg(function);
- errmsg("' invoked with archive structure in state '");
- write_all_states(a->state);
- errmsg("', should be in state '");
- write_all_states(state);
- errmsg("'\n");
+ /* If we're already FATAL, don't overwrite the error. */
+ if (a->state != ARCHIVE_STATE_FATAL)
+ archive_set_error(a, -1,
+ "INTERNAL ERROR: Function '%s' invoked with"
+ " archive structure in state '%s',"
+ " should be in state '%s'",
+ function,
+ write_all_states(states1, a->state),
+ write_all_states(states2, a->state));
+ a->state = ARCHIVE_STATE_FATAL;
+#if ARCHIVE_VERSION_NUMBER < 3000000
+ // XXXX This should be identical to the old behavior.
+ errmsg(archive_error_string(a));
diediedie();
+#else
+ // XXXX This is the proposed new behavior.
+ return (ARCHIVE_FATAL);
+#endif
}
+ return ARCHIVE_OK;
}
diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h
index 103878d2..d23414cd 100644
--- a/libarchive/archive_entry.h
+++ b/libarchive/archive_entry.h
@@ -28,10 +28,8 @@
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
-/* Needed if archive_entry.h is used without archive.h */
-#ifndef ARCHIVE_VERSION_NUMBER
-#define ARCHIVE_VERSION_NUMBER 3000000
-#endif
+/* Note: Compiler will complain if this does not match archive.h! */
+#define ARCHIVE_VERSION_NUMBER 2008900
/*
* Note: archive_entry.h is for use outside of libarchive; the
diff --git a/libarchive/archive_private.h b/libarchive/archive_private.h
index df83b769..862eb032 100644
--- a/libarchive/archive_private.h
+++ b/libarchive/archive_private.h
@@ -47,13 +47,13 @@
#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
-#define ARCHIVE_STATE_ANY 0xFFFFU
#define ARCHIVE_STATE_NEW 1U
#define ARCHIVE_STATE_HEADER 2U
#define ARCHIVE_STATE_DATA 4U
#define ARCHIVE_STATE_EOF 0x10U
#define ARCHIVE_STATE_CLOSED 0x20U
#define ARCHIVE_STATE_FATAL 0x8000U
+#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL)
struct archive_vtable {
int (*archive_close)(struct archive *);
@@ -102,9 +102,16 @@ struct archive {
struct archive_string error_string;
};
-/* Check magic value and state; exit if it isn't valid. */
-void __archive_check_magic(struct archive *, unsigned int magic,
+/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
+int __archive_check_magic(struct archive *, unsigned int magic,
unsigned int state, const char *func);
+#define archive_check_magic(a, expected_magic, allowed_states, function_name) \
+ do { \
+ int magic_test = __archive_check_magic((a), (expected_magic), \
+ (allowed_states), (function_name)); \
+ if (magic_test == ARCHIVE_FATAL) \
+ return ARCHIVE_FATAL; \
+ } while (0)
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
index 26d3a6e4..5c99e08f 100644
--- a/libarchive/archive_read.c
+++ b/libarchive/archive_read.c
@@ -115,8 +115,11 @@ archive_read_extract_set_skip_file(struct archive *_a, int64_t d, int64_t i)
#endif
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_extract_set_skip_file");
+
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_extract_set_skip_file"))
+ return;
+
a->skip_file_dev = d;
a->skip_file_ino = i;
}
@@ -134,14 +137,12 @@ archive_read_set_format_options(struct archive *_a, const char *s)
size_t i;
int len, r;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_set_format_options");
if (s == NULL || *s == '\0')
return (ARCHIVE_OK);
a = (struct archive_read *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_set_format_options");
len = 0;
for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
format = &a->formats[i];
@@ -181,14 +182,12 @@ archive_read_set_filter_options(struct archive *_a, const char *s)
char key[64], val[64];
int len, r;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_set_filter_options");
if (s == NULL || *s == '\0')
return (ARCHIVE_OK);
a = (struct archive_read *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_set_filter_options");
len = 0;
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
bidder = filter->bidder;
@@ -224,7 +223,7 @@ archive_read_set_options(struct archive *_a, const char *s)
{
int r;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_set_options");
archive_clear_error(_a);
@@ -308,7 +307,7 @@ archive_read_open2(struct archive *_a, void *client_data,
struct archive_read_filter *filter;
int e;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_open");
archive_clear_error(&a->archive);
@@ -424,7 +423,7 @@ archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
struct archive_read *a = (struct archive_read *)_a;
int slot, ret;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_read_next_header");
@@ -562,7 +561,7 @@ int64_t
archive_read_header_position(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_header_position");
return (a->header_position);
}
@@ -682,7 +681,7 @@ archive_read_data_skip(struct archive *_a)
int64_t offset;
#endif
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
"archive_read_data_skip");
if (a->format->read_data_skip != NULL)
@@ -720,7 +719,7 @@ archive_read_data_block(struct archive *_a,
#endif
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
"archive_read_data_block");
if (a->format->read_data == NULL) {
@@ -772,10 +771,11 @@ _archive_read_close(struct archive *_a)
struct archive_read *a = (struct archive_read *)_a;
int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_close");
+ archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
archive_clear_error(&a->archive);
- a->archive.state = ARCHIVE_STATE_CLOSED;
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
/* TODO: Clean up the formatters. */
@@ -798,9 +798,12 @@ _archive_read_free(struct archive *_a)
int slots;
int r = ARCHIVE_OK;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_free");
- if (a->archive.state != ARCHIVE_STATE_CLOSED)
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+ if (a->archive.state != ARCHIVE_STATE_CLOSED
+ && a->archive.state != ARCHIVE_STATE_FATAL)
r = archive_read_close(&a->archive);
/* Call cleanup functions registered by optional components. */
@@ -893,7 +896,7 @@ __archive_read_register_format(struct archive_read *a,
{
int i, number_slots;
- __archive_check_magic(&a->archive,
+ archive_check_magic(&a->archive,
ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"__archive_read_register_format");
@@ -928,10 +931,6 @@ __archive_read_get_bidder(struct archive_read *a)
{
int i, number_slots;
- __archive_check_magic(&a->archive,
- ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "__archive_read_get_bidder");
-
number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
for (i = 0; i < number_slots; i++) {
diff --git a/libarchive/archive_read_data_into_fd.c b/libarchive/archive_read_data_into_fd.c
index 1ede6c61..afe55a77 100644
--- a/libarchive/archive_read_data_into_fd.c
+++ b/libarchive/archive_read_data_into_fd.c
@@ -59,7 +59,8 @@ archive_read_data_into_fd(struct archive *a, int fd)
#endif
off_t output_offset;
- __archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, "archive_read_data_into_fd");
+ archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_into_fd");
total_written = 0;
output_offset = 0;
diff --git a/libarchive/archive_read_disk.c b/libarchive/archive_read_disk.c
index 5fc0aee0..ba03a38f 100644
--- a/libarchive/archive_read_disk.c
+++ b/libarchive/archive_read_disk.c
@@ -64,9 +64,12 @@ archive_read_disk_gname(struct archive *_a, int64_t gid)
#endif
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (a->lookup_gname != NULL)
- return ((*a->lookup_gname)(a->lookup_gname_data, gid));
- return (NULL);
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
+ return (NULL);
+ if (a->lookup_gname == NULL)
+ return (NULL);
+ return ((*a->lookup_gname)(a->lookup_gname_data, gid));
}
#if ARCHIVE_VERSION_NUMBER < 3000000
@@ -78,9 +81,12 @@ archive_read_disk_uname(struct archive *_a, int64_t uid)
#endif
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (a->lookup_uname != NULL)
- return ((*a->lookup_uname)(a->lookup_uname_data, uid));
- return (NULL);
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
+ return (NULL);
+ if (a->lookup_uname == NULL)
+ return (NULL);
+ return ((*a->lookup_uname)(a->lookup_uname_data, uid));
}
#if ARCHIVE_VERSION_NUMBER < 3000000
@@ -98,7 +104,7 @@ archive_read_disk_set_gname_lookup(struct archive *_a,
#endif
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
@@ -125,7 +131,7 @@ archive_read_disk_set_uname_lookup(struct archive *_a,
#endif
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
@@ -163,11 +169,16 @@ _archive_read_free(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
(a->cleanup_gname)(a->lookup_gname_data);
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
(a->cleanup_uname)(a->lookup_uname_data);
archive_string_free(&a->archive.error_string);
+ a->archive.magic = 0;
free(a);
return (ARCHIVE_OK);
}
@@ -175,6 +186,8 @@ _archive_read_free(struct archive *_a)
static int
_archive_read_close(struct archive *_a)
{
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
(void)_a; /* UNUSED */
return (ARCHIVE_OK);
}
@@ -183,6 +196,8 @@ int
archive_read_disk_set_symlink_logical(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
a->symlink_mode = 'L';
a->follow_symlinks = 1;
return (ARCHIVE_OK);
@@ -192,6 +207,8 @@ int
archive_read_disk_set_symlink_physical(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
a->symlink_mode = 'P';
a->follow_symlinks = 0;
return (ARCHIVE_OK);
@@ -201,6 +218,8 @@ int
archive_read_disk_set_symlink_hybrid(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
a->symlink_mode = 'H';
a->follow_symlinks = 1; /* Follow symlinks initially. */
return (ARCHIVE_OK);
diff --git a/libarchive/archive_read_support_format_ar.c b/libarchive/archive_read_support_format_ar.c
index cfbd4cae..94836706 100644
--- a/libarchive/archive_read_support_format_ar.c
+++ b/libarchive/archive_read_support_format_ar.c
@@ -101,6 +101,9 @@ archive_read_support_format_ar(struct archive *_a)
struct ar *ar;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_ar");
+
ar = (struct ar *)malloc(sizeof(*ar));
if (ar == NULL) {
archive_set_error(&a->archive, ENOMEM,
diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c
index 04cceba4..d3bd0275 100644
--- a/libarchive/archive_read_support_format_cpio.c
+++ b/libarchive/archive_read_support_format_cpio.c
@@ -176,6 +176,9 @@ archive_read_support_format_cpio(struct archive *_a)
struct cpio *cpio;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_cpio");
+
cpio = (struct cpio *)malloc(sizeof(*cpio));
if (cpio == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
diff --git a/libarchive/archive_read_support_format_empty.c b/libarchive/archive_read_support_format_empty.c
index d19c766a..73f51b69 100644
--- a/libarchive/archive_read_support_format_empty.c
+++ b/libarchive/archive_read_support_format_empty.c
@@ -47,6 +47,9 @@ archive_read_support_format_empty(struct archive *_a)
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_empty");
+
r = __archive_read_register_format(a,
NULL,
NULL,
diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index 1694a91a..b667cf87 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -426,6 +426,9 @@ archive_read_support_format_iso9660(struct archive *_a)
struct iso9660 *iso9660;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_iso9660");
+
iso9660 = (struct iso9660 *)malloc(sizeof(*iso9660));
if (iso9660 == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't allocate iso9660 data");
diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
index f9d6ca89..f938c07b 100644
--- a/libarchive/archive_read_support_format_mtree.c
+++ b/libarchive/archive_read_support_format_mtree.c
@@ -144,6 +144,9 @@ archive_read_support_format_mtree(struct archive *_a)
struct mtree *mtree;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_mtree");
+
mtree = (struct mtree *)malloc(sizeof(*mtree));
if (mtree == NULL) {
archive_set_error(&a->archive, ENOMEM,
diff --git a/libarchive/archive_read_support_format_raw.c b/libarchive/archive_read_support_format_raw.c
index 89e6940d..ea7b26c3 100644
--- a/libarchive/archive_read_support_format_raw.c
+++ b/libarchive/archive_read_support_format_raw.c
@@ -63,6 +63,9 @@ archive_read_support_format_raw(struct archive *_a)
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_raw");
+
info = (struct raw_info *)calloc(1, sizeof(*info));
if (info == NULL) {
archive_set_error(&a->archive, ENOMEM,
diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index c60d04ba..b96ac724 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -239,6 +239,8 @@ static wchar_t *utf8_decode(struct tar *, const char *, size_t length);
int
archive_read_support_format_gnutar(struct archive *a)
{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_gnutar");
return (archive_read_support_format_tar(a));
}
@@ -250,6 +252,9 @@ archive_read_support_format_tar(struct archive *_a)
struct tar *tar;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
+
tar = (struct tar *)malloc(sizeof(*tar));
if (tar == NULL) {
archive_set_error(&a->archive, ENOMEM,
diff --git a/libarchive/archive_read_support_format_xar.c b/libarchive/archive_read_support_format_xar.c
index 76452c43..02c3b53a 100644
--- a/libarchive/archive_read_support_format_xar.c
+++ b/libarchive/archive_read_support_format_xar.c
@@ -73,6 +73,8 @@ int
archive_read_support_format_xar(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Xar not supported on this platform");
@@ -435,6 +437,9 @@ archive_read_support_format_xar(struct archive *_a)
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
+
xar = (struct xar *)calloc(1, sizeof(*xar));
if (xar == NULL) {
archive_set_error(&a->archive, ENOMEM,
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
index 044d9de5..8f04b542 100644
--- a/libarchive/archive_read_support_format_zip.c
+++ b/libarchive/archive_read_support_format_zip.c
@@ -156,6 +156,9 @@ archive_read_support_format_zip(struct archive *_a)
struct zip *zip;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_zip");
+
zip = (struct zip *)malloc(sizeof(*zip));
if (zip == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data");
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
index bca4b796..1a6c80c2 100644
--- a/libarchive/archive_write.c
+++ b/libarchive/archive_write.c
@@ -143,7 +143,7 @@ archive_write_set_format_options(struct archive *_a, const char *s)
char key[64], val[64];
int len, r, ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_format_options");
archive_clear_error(&a->archive);
@@ -188,7 +188,7 @@ archive_write_set_compressor_options(struct archive *_a, const char *s)
int len, r;
int ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_compressor_options");
archive_clear_error(&a->archive);
@@ -251,7 +251,7 @@ int
archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
a->bytes_per_block = bytes_per_block;
return (ARCHIVE_OK);
@@ -264,7 +264,7 @@ int
archive_write_get_bytes_per_block(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
return (a->bytes_per_block);
}
@@ -277,7 +277,7 @@ int
archive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block");
a->bytes_in_last_block = bytes;
return (ARCHIVE_OK);
@@ -290,7 +290,7 @@ int
archive_write_get_bytes_in_last_block(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block");
return (a->bytes_in_last_block);
}
@@ -309,7 +309,7 @@ archive_write_set_skip_file(struct archive *_a, int64_t d, int64_t i)
#endif
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_set_skip_file");
a->skip_file_dev = d;
a->skip_file_ino = i;
@@ -324,8 +324,7 @@ __archive_write_allocate_filter(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write_filter *f;
- __archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_allocate_filter");
+
f = calloc(1, sizeof(*f));
f->archive = _a;
if (a->filter_first == NULL)
@@ -344,6 +343,8 @@ __archive_write_filter(struct archive_write_filter *f,
const void *buff, size_t length)
{
int r;
+ if (length == 0)
+ return(ARCHIVE_OK);
r = (f->write)(f, buff, length);
f->bytes_written += length;
return (r);
@@ -535,7 +536,7 @@ archive_write_open(struct archive *_a, void *client_data,
struct archive_write_filter *client_filter;
int ret;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_open");
archive_clear_error(&a->archive);
@@ -567,24 +568,17 @@ _archive_write_close(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
- /*
- * It's perfectly reasonable to call close() as part of
- * routine cleanup, even after an error, so we're a little
- * tolerant of being called in odd states.
- */
- if (a->archive.state & ARCHIVE_STATE_FATAL)
- return (ARCHIVE_FATAL);
- archive_clear_error(&a->archive);
- if (a->archive.state & (ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED))
- return (ARCHIVE_OK);
-
- __archive_check_magic(&a->archive,
- ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL,
"archive_write_close");
+ if (a->archive.state == ARCHIVE_STATE_NEW
+ || a->archive.state == ARCHIVE_STATE_CLOSED)
+ return (ARCHIVE_OK); // Okay to close() when not open.
+
+ archive_clear_error(&a->archive);
/* Finish the last entry. */
- if (a->archive.state & ARCHIVE_STATE_DATA)
+ if (a->archive.state == ARCHIVE_STATE_DATA)
r = ((a->format_finish_entry)(a));
/* Finish off the archive. */
@@ -601,7 +595,8 @@ _archive_write_close(struct archive *_a)
if (r1 < r)
r = r1;
- a->archive.state = ARCHIVE_STATE_CLOSED;
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
return (r);
}
@@ -638,10 +633,12 @@ _archive_write_free(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
int r = ARCHIVE_OK, r1;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_free");
- if (a->archive.state != ARCHIVE_STATE_CLOSED
- && a->archive.state != ARCHIVE_STATE_FATAL)
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ /* It is okay to call free() in state FATAL. */
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free");
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
r = archive_write_close(&a->archive);
/* Release format resources. */
@@ -671,7 +668,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
struct archive_write *a = (struct archive_write *)_a;
int ret, r2;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header");
archive_clear_error(&a->archive);
@@ -712,7 +709,7 @@ _archive_write_finish_entry(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
int ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_finish_entry");
if (a->archive.state & ARCHIVE_STATE_DATA)
@@ -728,7 +725,7 @@ static ssize_t
_archive_write_data(struct archive *_a, const void *buff, size_t s)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
archive_clear_error(&a->archive);
return ((a->format_write_data)(a, buff, s));
diff --git a/libarchive/archive_write_add_filter_bzip2.c b/libarchive/archive_write_add_filter_bzip2.c
index 6d1b3567..35d29b95 100644
--- a/libarchive/archive_write_add_filter_bzip2.c
+++ b/libarchive/archive_write_add_filter_bzip2.c
@@ -100,8 +100,8 @@ archive_write_add_filter_bzip2(struct archive *_a)
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_data *data;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_bzip2");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_bzip2");
data = calloc(1, sizeof(*data));
if (data == NULL) {
diff --git a/libarchive/archive_write_add_filter_compress.c b/libarchive/archive_write_add_filter_compress.c
index 7e3ef6bb..0ae98ea5 100644
--- a/libarchive/archive_write_add_filter_compress.c
+++ b/libarchive/archive_write_add_filter_compress.c
@@ -132,8 +132,8 @@ archive_write_add_filter_compress(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_compress");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_compress");
f->open = &archive_compressor_compress_open;
f->code = ARCHIVE_COMPRESSION_COMPRESS;
f->name = "compress";
diff --git a/libarchive/archive_write_add_filter_gzip.c b/libarchive/archive_write_add_filter_gzip.c
index 23dabe53..786ae98a 100644
--- a/libarchive/archive_write_add_filter_gzip.c
+++ b/libarchive/archive_write_add_filter_gzip.c
@@ -101,8 +101,8 @@ archive_write_add_filter_gzip(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_data *data;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_gzip");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_gzip");
data = calloc(1, sizeof(*data));
if (data == NULL) {
diff --git a/libarchive/archive_write_add_filter_program.c b/libarchive/archive_write_add_filter_program.c
index 90c5f11d..3dcc9df7 100644
--- a/libarchive/archive_write_add_filter_program.c
+++ b/libarchive/archive_write_add_filter_program.c
@@ -102,8 +102,8 @@ archive_write_add_filter_program(struct archive *_a, const char *cmd)
struct archive_write *a = (struct archive_write *)_a;
struct private_data *data;
static const char *prefix = "Program: ";
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_program");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_program");
data = calloc(1, sizeof(*data));
if (data == NULL) {
archive_set_error(&a->archive, ENOMEM, "Out of memory");
diff --git a/libarchive/archive_write_add_filter_xz.c b/libarchive/archive_write_add_filter_xz.c
index 2e21c60a..83cdb635 100644
--- a/libarchive/archive_write_add_filter_xz.c
+++ b/libarchive/archive_write_add_filter_xz.c
@@ -107,8 +107,6 @@ common_setup(struct archive_write_filter *f)
{
struct private_data *data;
struct archive_write *a = (struct archive_write *)f->archive;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_xz");
data = calloc(1, sizeof(*data));
if (data == NULL) {
archive_set_error(&a->archive, ENOMEM, "Out of memory");
@@ -129,8 +127,13 @@ common_setup(struct archive_write_filter *f)
int
archive_write_add_filter_xz(struct archive *_a)
{
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- int r = common_setup(f);
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_xz");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
if (r == ARCHIVE_OK) {
f->code = ARCHIVE_COMPRESSION_XZ;
f->name = "xz";
@@ -144,8 +147,13 @@ archive_write_add_filter_xz(struct archive *_a)
int
archive_write_add_filter_lzma(struct archive *_a)
{
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- int r = common_setup(f);
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_lzma");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
if (r == ARCHIVE_OK) {
f->code = ARCHIVE_COMPRESSION_LZMA;
f->name = "lzma";
diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c
index 5f5ade9d..92dbe35e 100644
--- a/libarchive/archive_write_disk.c
+++ b/libarchive/archive_write_disk.c
@@ -360,7 +360,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
struct fixup_entry *fe;
int ret, r;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_disk_header");
archive_clear_error(&a->archive);
@@ -598,7 +598,7 @@ archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
#endif
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
a->skip_file_dev = d;
a->skip_file_ino = i;
@@ -698,7 +698,7 @@ _archive_write_disk_data_block(struct archive *_a,
struct archive_write_disk *a = (struct archive_write_disk *)_a;
ssize_t r;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data_block");
a->offset = offset;
@@ -718,7 +718,7 @@ _archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
return (write_data_block(a, buff, size));
@@ -730,7 +730,7 @@ _archive_write_disk_finish_entry(struct archive *_a)
struct archive_write_disk *a = (struct archive_write_disk *)_a;
int ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_finish_entry");
if (a->archive.state & ARCHIVE_STATE_HEADER)
@@ -870,7 +870,7 @@ archive_write_disk_set_group_lookup(struct archive *_a,
#endif
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
a->lookup_gid = lookup_gid;
@@ -894,7 +894,7 @@ archive_write_disk_set_user_lookup(struct archive *_a,
#endif
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
a->lookup_uid = lookup_uid;
@@ -1309,7 +1309,7 @@ _archive_write_disk_close(struct archive *_a)
struct fixup_entry *next, *p;
int ret;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_disk_close");
ret = _archive_write_disk_finish_entry(&a->archive);
@@ -1373,8 +1373,13 @@ _archive_write_disk_close(struct archive *_a)
static int
_archive_write_disk_free(struct archive *_a)
{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct archive_write_disk *a;
int ret;
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
+ a = (struct archive_write_disk *)_a;
ret = _archive_write_disk_close(&a->archive);
if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
(a->cleanup_gid)(a->lookup_gid_data);
@@ -1385,6 +1390,7 @@ _archive_write_disk_free(struct archive *_a)
archive_string_free(&a->_name_data);
archive_string_free(&a->archive.error_string);
archive_string_free(&a->path_safe);
+ a->archive.magic = 0;
free(a);
return (ret);
}
diff --git a/libarchive/archive_write_set_format_ar.c b/libarchive/archive_write_set_format_ar.c
index 3e70f363..efe2725f 100644
--- a/libarchive/archive_write_set_format_ar.c
+++ b/libarchive/archive_write_set_format_ar.c
@@ -86,7 +86,11 @@ int
archive_write_set_format_ar_bsd(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- int r = archive_write_set_format_ar(a);
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ar_bsd");
+ r = archive_write_set_format_ar(a);
if (r == ARCHIVE_OK) {
a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
a->archive.archive_format_name = "ar (BSD)";
@@ -98,7 +102,11 @@ int
archive_write_set_format_ar_svr4(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- int r = archive_write_set_format_ar(a);
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ar_svr4");
+ r = archive_write_set_format_ar(a);
if (r == ARCHIVE_OK) {
a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU;
a->archive.archive_format_name = "ar (GNU/SVR4)";
diff --git a/libarchive/archive_write_set_format_by_name.c b/libarchive/archive_write_set_format_by_name.c
index 3c08d060..0851c1ec 100644
--- a/libarchive/archive_write_set_format_by_name.c
+++ b/libarchive/archive_write_set_format_by_name.c
@@ -75,5 +75,6 @@ archive_write_set_format_by_name(struct archive *a, const char *name)
}
archive_set_error(a, EINVAL, "No such format '%s'", name);
+ a->state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
diff --git a/libarchive/archive_write_set_format_cpio.c b/libarchive/archive_write_set_format_cpio.c
index 29a6fb6e..28e91e19 100644
--- a/libarchive/archive_write_set_format_cpio.c
+++ b/libarchive/archive_write_set_format_cpio.c
@@ -85,6 +85,9 @@ archive_write_set_format_cpio(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct cpio *cpio;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio");
+
/* If someone else was already registered, unregister them. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
diff --git a/libarchive/archive_write_set_format_cpio_newc.c b/libarchive/archive_write_set_format_cpio_newc.c
index bf4f7435..b9d21c52 100644
--- a/libarchive/archive_write_set_format_cpio_newc.c
+++ b/libarchive/archive_write_set_format_cpio_newc.c
@@ -87,6 +87,9 @@ archive_write_set_format_cpio_newc(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct cpio *cpio;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_newc");
+
/* If someone else was already registered, unregister them. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
index e7bfaf36..5329d821 100644
--- a/libarchive/archive_write_set_format_iso9660.c
+++ b/libarchive/archive_write_set_format_iso9660.c
@@ -1158,6 +1158,9 @@ archive_write_set_format_iso9660(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct iso9660 *iso9660;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660");
+
/* If another format was already registered, unregister it. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c
index 054cbc14..5b2bf022 100644
--- a/libarchive/archive_write_set_format_mtree.c
+++ b/libarchive/archive_write_set_format_mtree.c
@@ -1015,6 +1015,9 @@ archive_write_set_format_mtree(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct mtree_writer *mtree;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_mtree");
+
if (a->format_destroy != NULL)
(a->format_destroy)(a);
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
index cab8f375..771de2a5 100644
--- a/libarchive/archive_write_set_format_pax.c
+++ b/libarchive/archive_write_set_format_pax.c
@@ -99,6 +99,10 @@ archive_write_set_format_pax_restricted(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_pax_restricted");
+
r = archive_write_set_format_pax(&a->archive);
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
a->archive.archive_format_name = "restricted POSIX pax interchange";
@@ -114,6 +118,9 @@ archive_write_set_format_pax(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct pax *pax;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_pax");
+
if (a->format_destroy != NULL)
(a->format_destroy)(a);
diff --git a/libarchive/archive_write_set_format_shar.c b/libarchive/archive_write_set_format_shar.c
index 727a6e40..52bb93c9 100644
--- a/libarchive/archive_write_set_format_shar.c
+++ b/libarchive/archive_write_set_format_shar.c
@@ -106,6 +106,9 @@ archive_write_set_format_shar(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct shar *shar;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_shar");
+
/* If someone else was already registered, unregister them. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
diff --git a/libarchive/archive_write_set_format_ustar.c b/libarchive/archive_write_set_format_ustar.c
index a76081ce..8885b746 100644
--- a/libarchive/archive_write_set_format_ustar.c
+++ b/libarchive/archive_write_set_format_ustar.c
@@ -162,6 +162,9 @@ archive_write_set_format_ustar(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct ustar *ustar;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ustar");
+
/* If someone else was already registered, unregister them. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c
index b857df2e..4ed1bfa7 100644
--- a/libarchive/archive_write_set_format_zip.c
+++ b/libarchive/archive_write_set_format_zip.c
@@ -227,6 +227,9 @@ archive_write_set_format_zip(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct zip *zip;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_zip");
+
/* If another format was already registered, unregister it. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);