Provides a clear separation between RW data and RO executable code.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
bidder = a->bidders;
for (i = 0; i < number_bidders; i++, bidder++) {
- if (bidder->bid != NULL) {
- bid = (bidder->bid)(bidder, a->filter);
- if (bid > best_bid) {
- best_bid = bid;
- best_bidder = bidder;
- }
+ if (bidder->vtable == NULL)
+ continue;
+ bid = (bidder->vtable->bid)(bidder, a->filter);
+ if (bid > best_bid) {
+ best_bid = bid;
+ best_bidder = bidder;
}
}
filter->archive = a;
filter->upstream = a->filter;
a->filter = filter;
- r = (best_bidder->init)(a->filter);
+ r = (best_bidder->vtable->init)(a->filter);
if (r != ARCHIVE_OK) {
__archive_read_free_filters(a);
return (ARCHIVE_FATAL);
/* Release the bidder objects. */
n = sizeof(a->bidders)/sizeof(a->bidders[0]);
for (i = 0; i < n; i++) {
- if (a->bidders[i].free != NULL) {
- (a->bidders[i].free)(&a->bidders[i]);
- }
+ if (a->bidders[i].vtable == NULL ||
+ a->bidders[i].vtable->free == NULL)
+ continue;
+ (a->bidders[i].vtable->free)(&a->bidders[i]);
}
/* Release passphrase list. */
number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
for (i = 0; i < number_slots; i++) {
- if (a->bidders[i].bid == NULL) {
- memset(a->bidders + i, 0, sizeof(a->bidders[0]));
- *bidder = (a->bidders + i);
- return (ARCHIVE_OK);
- }
+ if (a->bidders[i].vtable != NULL)
+ continue;
+ memset(a->bidders + i, 0, sizeof(a->bidders[0]));
+ *bidder = (a->bidders + i);
+ return (ARCHIVE_OK);
}
archive_set_error(&a->archive, ENOMEM,
filter->archive = a;
filter->upstream = a->filter;
a->filter = filter;
- r2 = (bidder->init)(a->filter);
+ r2 = (bidder->vtable->init)(a->filter);
if (r2 != ARCHIVE_OK) {
__archive_read_free_filters(a);
return (ARCHIVE_FATAL);
filter->archive = a;
filter->upstream = a->filter;
a->filter = filter;
- r = (bidder->init)(a->filter);
+ r = (bidder->vtable->init)(a->filter);
if (r != ARCHIVE_OK) {
__archive_read_free_filters(a);
return (ARCHIVE_FATAL);
struct archive_read_filter_bidder;
struct archive_read_filter;
+struct archive_read_filter_bidder_vtable {
+ /* Taste the upstream filter to see if we handle this. */
+ int (*bid)(struct archive_read_filter_bidder *,
+ struct archive_read_filter *);
+ /* Initialize a newly-created filter. */
+ int (*init)(struct archive_read_filter *);
+ /* Release the bidder's configuration data. */
+ void (*free)(struct archive_read_filter_bidder *);
+};
+
/*
* How bidding works for filters:
* * The bid manager initializes the client-provided reader as the
void *data;
/* Name of the filter */
const char *name;
- /* Taste the upstream filter to see if we handle this. */
- int (*bid)(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
- /* Initialize a newly-created filter. */
- int (*init)(struct archive_read_filter *);
- /* Release the bidder's configuration data. */
- void (*free)(struct archive_read_filter_bidder *);
+ const struct archive_read_filter_bidder_vtable *vtable;
};
/*
}
#endif
+static const struct archive_read_filter_bidder_vtable
+bzip2_bidder_vtable = {
+ .bid = bzip2_reader_bid,
+ .init = bzip2_reader_init,
+};
+
int
archive_read_support_filter_bzip2(struct archive *_a)
{
reader->data = NULL;
reader->name = "bzip2";
- reader->bid = bzip2_reader_bid;
- reader->init = bzip2_reader_init;
- reader->free = NULL;
+ reader->vtable = &bzip2_bidder_vtable;
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
return (ARCHIVE_OK);
#else
}
#endif
+static const struct archive_read_filter_bidder_vtable
+compress_bidder_vtable = {
+ .bid = compress_bidder_bid,
+ .init = compress_bidder_init,
+};
+
int
archive_read_support_filter_compress(struct archive *_a)
{
bidder->data = NULL;
bidder->name = "compress (.Z)";
- bidder->bid = compress_bidder_bid;
- bidder->init = compress_bidder_init;
- bidder->free = NULL;
+ bidder->vtable = &compress_bidder_vtable;
return (ARCHIVE_OK);
}
static int grzip_bidder_init(struct archive_read_filter *);
+static const struct archive_read_filter_bidder_vtable
+grzip_bidder_vtable = {
+ .bid = grzip_bidder_bid,
+ .init = grzip_bidder_init,
+};
+
int
archive_read_support_filter_grzip(struct archive *_a)
{
return (ARCHIVE_FATAL);
reader->data = NULL;
- reader->bid = grzip_bidder_bid;
- reader->init = grzip_bidder_init;
- reader->free = NULL;
+ reader->vtable = &grzip_bidder_vtable;
/* This filter always uses an external program. */
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
"Using external grzip program for grzip decompression");
}
#endif
+static const struct archive_read_filter_bidder_vtable
+gzip_bidder_vtable = {
+ .bid = gzip_bidder_bid,
+ .init = gzip_bidder_init,
+};
+
int
archive_read_support_filter_gzip(struct archive *_a)
{
bidder->data = NULL;
bidder->name = "gzip";
- bidder->bid = gzip_bidder_bid;
- bidder->init = gzip_bidder_init;
- bidder->free = NULL; /* No data, so no cleanup necessary. */
+ bidder->vtable = &gzip_bidder_vtable;
/* Signal the extent of gzip support with the return value here. */
#if HAVE_ZLIB_H
return (ARCHIVE_OK);
static int lrzip_bidder_init(struct archive_read_filter *);
+static const struct archive_read_filter_bidder_vtable
+lrzip_bidder_vtable = {
+ .bid = lrzip_bidder_bid,
+ .init = lrzip_bidder_init,
+};
+
int
archive_read_support_filter_lrzip(struct archive *_a)
{
reader->data = NULL;
reader->name = "lrzip";
- reader->bid = lrzip_bidder_bid;
- reader->init = lrzip_bidder_init;
- reader->free = NULL;
+ reader->vtable = &lrzip_bidder_vtable;
/* This filter always uses an external program. */
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
"Using external lrzip program for lrzip decompression");
const void **);
#endif
+static const struct archive_read_filter_bidder_vtable
+lz4_bidder_vtable = {
+ .bid = lz4_reader_bid,
+ .init = lz4_reader_init,
+};
+
int
archive_read_support_filter_lz4(struct archive *_a)
{
reader->data = NULL;
reader->name = "lz4";
- reader->bid = lz4_reader_bid;
- reader->init = lz4_reader_init;
- reader->free = NULL;
+ reader->vtable = &lz4_bidder_vtable;
#if defined(HAVE_LIBLZ4)
return (ARCHIVE_OK);
#else
struct archive_read_filter *);
static int lzop_bidder_init(struct archive_read_filter *);
+static const struct archive_read_filter_bidder_vtable
+lzop_bidder_vtable = {
+ .bid = lzop_bidder_bid,
+ .init = lzop_bidder_init,
+};
+
int
archive_read_support_filter_lzop(struct archive *_a)
{
return (ARCHIVE_FATAL);
reader->data = NULL;
- reader->bid = lzop_bidder_bid;
- reader->init = lzop_bidder_init;
- reader->free = NULL;
+ reader->vtable = &lzop_bidder_vtable;
/* Signal the extent of lzop support with the return value here. */
#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
return (ARCHIVE_OK);
static int program_filter_close(struct archive_read_filter *);
static void free_state(struct program_bidder *);
+static const struct archive_read_filter_bidder_vtable
+program_bidder_vtable = {
+ .bid = program_bidder_bid,
+ .init = program_bidder_init,
+ .free = program_bidder_free,
+};
+
static int
set_bidder_signature(struct archive_read_filter_bidder *bidder,
struct program_bidder *state, const void *signature, size_t signature_len)
* Fill in the bidder object.
*/
bidder->data = state;
- bidder->bid = program_bidder_bid;
- bidder->init = program_bidder_init;
- bidder->free = program_bidder_free;
+ bidder->vtable = &program_bidder_vtable;
return (ARCHIVE_OK);
}
}
#endif
+static const struct archive_read_filter_bidder_vtable
+rpm_bidder_vtable = {
+ .bid = rpm_bidder_bid,
+ .init = rpm_bidder_init,
+};
+
int
archive_read_support_filter_rpm(struct archive *_a)
{
bidder->data = NULL;
bidder->name = "rpm";
- bidder->bid = rpm_bidder_bid;
- bidder->init = rpm_bidder_init;
- bidder->free = NULL;
+ bidder->vtable = &rpm_bidder_vtable;
return (ARCHIVE_OK);
}
}
#endif
+static const struct archive_read_filter_bidder_vtable
+uudecode_bidder_vtable = {
+ .bid = uudecode_bidder_bid,
+ .init = uudecode_bidder_init,
+};
+
int
archive_read_support_filter_uu(struct archive *_a)
{
bidder->data = NULL;
bidder->name = "uu";
- bidder->bid = uudecode_bidder_bid;
- bidder->init = uudecode_bidder_init;
- bidder->free = NULL;
+ bidder->vtable = &uudecode_bidder_vtable;
return (ARCHIVE_OK);
}
}
#endif
+static const struct archive_read_filter_bidder_vtable
+xz_bidder_vtable = {
+ .bid = xz_bidder_bid,
+ .init = xz_bidder_init,
+};
+
int
archive_read_support_filter_xz(struct archive *_a)
{
bidder->data = NULL;
bidder->name = "xz";
- bidder->bid = xz_bidder_bid;
- bidder->init = xz_bidder_init;
- bidder->free = NULL;
+ bidder->vtable = &xz_bidder_vtable;
#if HAVE_LZMA_H && HAVE_LIBLZMA
return (ARCHIVE_OK);
#else
}
#endif
+static const struct archive_read_filter_bidder_vtable
+lzma_bidder_vtable = {
+ .bid = lzma_bidder_bid,
+ .init = lzma_bidder_init,
+};
+
int
archive_read_support_filter_lzma(struct archive *_a)
{
bidder->data = NULL;
bidder->name = "lzma";
- bidder->bid = lzma_bidder_bid;
- bidder->init = lzma_bidder_init;
- bidder->free = NULL;
+ bidder->vtable = &lzma_bidder_vtable;
#if HAVE_LZMA_H && HAVE_LIBLZMA
return (ARCHIVE_OK);
#else
}
#endif
+static const struct archive_read_filter_bidder_vtable
+lzip_bidder_vtable = {
+ .bid = lzip_bidder_bid,
+ .init = lzip_bidder_init,
+};
+
int
archive_read_support_filter_lzip(struct archive *_a)
{
bidder->data = NULL;
bidder->name = "lzip";
- bidder->bid = lzip_bidder_bid;
- bidder->init = lzip_bidder_init;
- bidder->free = NULL;
+ bidder->vtable = &lzip_bidder_vtable;
#if HAVE_LZMA_H && HAVE_LIBLZMA
return (ARCHIVE_OK);
#else
struct archive_read_filter *);
static int zstd_bidder_init(struct archive_read_filter *);
+static const struct archive_read_filter_bidder_vtable
+zstd_bidder_vtable = {
+ .bid = zstd_bidder_bid,
+ .init = zstd_bidder_init,
+};
+
int
archive_read_support_filter_zstd(struct archive *_a)
{
bidder->data = NULL;
bidder->name = "zstd";
- bidder->bid = zstd_bidder_bid;
- bidder->init = zstd_bidder_init;
- bidder->free = NULL;
+ bidder->vtable = &zstd_bidder_vtable;
#if HAVE_ZSTD_H && HAVE_LIBZSTD
return (ARCHIVE_OK);
#else