reader: introduce archive_read_filter_bidder::vtable

Provides a clear separation between RW data and RO executable code.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
This commit is contained in:
Emil Velikov committed 2021-10-23 19:26:23 +01:00
1 parent 0e0d31a7d2
commit 64b82ac5c8
15 files changed
+128 -66

No files matched your search

+16 -15
View File
@@ -561,12 +561,12 @@ choose_filters(struct archive_read *a)
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;
}
}
@@ -591,7 +591,7 @@ choose_filters(struct archive_read *a)
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);
@@ -1103,9 +1103,10 @@ _archive_read_free(struct archive *_a)
/* 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. */
@@ -1238,11 +1239,11 @@ __archive_read_get_bidder(struct archive_read *a,
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,
+2 -2
View File
@@ -135,7 +135,7 @@ archive_read_append_filter(struct archive *_a, int code)
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);
@@ -192,7 +192,7 @@ archive_read_append_filter_program_signature(struct archive *_a,
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);
+11 -7
View File
@@ -42,6 +42,16 @@ struct archive_read;
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
@@ -62,13 +72,7 @@ struct archive_read_filter_bidder {
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;
};
/*
@@ -80,6 +80,12 @@ archive_read_support_compression_bzip2(struct archive *a)
}
#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)
{
@@ -94,9 +100,7 @@ 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
@@ -149,6 +149,12 @@ archive_read_support_compression_compress(struct archive *a)
}
#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)
{
@@ -163,9 +169,7 @@ 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);
}
@@ -54,6 +54,12 @@ static int grzip_bidder_bid(struct archive_read_filter_bidder *,
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)
{
@@ -67,9 +73,7 @@ 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");
@@ -94,6 +94,12 @@ archive_read_support_compression_gzip(struct archive *a)
}
#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)
{
@@ -108,9 +114,7 @@ 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);
@@ -53,6 +53,12 @@ static int lrzip_bidder_bid(struct archive_read_filter_bidder *,
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)
{
@@ -67,9 +73,7 @@ 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");
+7 -3
View File
@@ -106,6 +106,12 @@ static ssize_t lz4_filter_read_legacy_stream(struct archive_read_filter *,
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)
{
@@ -120,9 +126,7 @@ 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
@@ -101,6 +101,12 @@ static int lzop_bidder_bid(struct archive_read_filter_bidder *,
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)
{
@@ -114,9 +120,7 @@ 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);
@@ -123,6 +123,13 @@ static ssize_t program_filter_read(struct archive_read_filter *,
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)
@@ -138,9 +145,7 @@ set_bidder_signature(struct archive_read_filter_bidder *bidder,
* 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);
}
+7 -3
View File
@@ -72,6 +72,12 @@ archive_read_support_compression_rpm(struct archive *a)
}
#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)
{
@@ -86,9 +92,7 @@ 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);
}
+7 -3
View File
@@ -76,6 +76,12 @@ archive_read_support_compression_uu(struct archive *a)
}
#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)
{
@@ -90,9 +96,7 @@ 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);
}
+21 -9
View File
@@ -108,6 +108,12 @@ archive_read_support_compression_xz(struct archive *a)
}
#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)
{
@@ -122,9 +128,7 @@ 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
@@ -142,6 +146,12 @@ archive_read_support_compression_lzma(struct archive *a)
}
#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)
{
@@ -156,9 +166,7 @@ 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
@@ -177,6 +185,12 @@ archive_read_support_compression_lzip(struct archive *a)
}
#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)
{
@@ -191,9 +205,7 @@ 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
@@ -79,6 +79,12 @@ static int zstd_bidder_bid(struct archive_read_filter_bidder *,
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)
{
@@ -93,9 +99,7 @@ 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