From: Emil Velikov Date: Sat, 14 Mar 2020 15:47:22 +0000 (+0000) Subject: reader: introduce archive_read_filter_bidder::vtable X-Git-Tag: v3.6.0~18^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64b82ac5c8cb5d822962af988dd075331d997b79;p=thirdparty%2Flibarchive.git reader: introduce archive_read_filter_bidder::vtable Provides a clear separation between RW data and RO executable code. Signed-off-by: Emil Velikov --- diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c index 01dcd5f1e..cf97524b3 100644 --- a/libarchive/archive_read.c +++ b/libarchive/archive_read.c @@ -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, diff --git a/libarchive/archive_read_append_filter.c b/libarchive/archive_read_append_filter.c index da7c55b9b..25dc4b2a2 100644 --- a/libarchive/archive_read_append_filter.c +++ b/libarchive/archive_read_append_filter.c @@ -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); diff --git a/libarchive/archive_read_private.h b/libarchive/archive_read_private.h index 539aae8ca..b3cee971e 100644 --- a/libarchive/archive_read_private.h +++ b/libarchive/archive_read_private.h @@ -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; }; /* diff --git a/libarchive/archive_read_support_filter_bzip2.c b/libarchive/archive_read_support_filter_bzip2.c index 3dd1f1def..b94457092 100644 --- a/libarchive/archive_read_support_filter_bzip2.c +++ b/libarchive/archive_read_support_filter_bzip2.c @@ -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 diff --git a/libarchive/archive_read_support_filter_compress.c b/libarchive/archive_read_support_filter_compress.c index 166b145c7..44a0fc8ec 100644 --- a/libarchive/archive_read_support_filter_compress.c +++ b/libarchive/archive_read_support_filter_compress.c @@ -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); } diff --git a/libarchive/archive_read_support_filter_grzip.c b/libarchive/archive_read_support_filter_grzip.c index 782720ca5..20fb18ae2 100644 --- a/libarchive/archive_read_support_filter_grzip.c +++ b/libarchive/archive_read_support_filter_grzip.c @@ -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"); diff --git a/libarchive/archive_read_support_filter_gzip.c b/libarchive/archive_read_support_filter_gzip.c index 67b9a9550..221b78ae0 100644 --- a/libarchive/archive_read_support_filter_gzip.c +++ b/libarchive/archive_read_support_filter_gzip.c @@ -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); diff --git a/libarchive/archive_read_support_filter_lrzip.c b/libarchive/archive_read_support_filter_lrzip.c index 81bbec253..77dae4b3d 100644 --- a/libarchive/archive_read_support_filter_lrzip.c +++ b/libarchive/archive_read_support_filter_lrzip.c @@ -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"); diff --git a/libarchive/archive_read_support_filter_lz4.c b/libarchive/archive_read_support_filter_lz4.c index cfa6870ee..eb8ee4916 100644 --- a/libarchive/archive_read_support_filter_lz4.c +++ b/libarchive/archive_read_support_filter_lz4.c @@ -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 diff --git a/libarchive/archive_read_support_filter_lzop.c b/libarchive/archive_read_support_filter_lzop.c index a2846b824..e231306ad 100644 --- a/libarchive/archive_read_support_filter_lzop.c +++ b/libarchive/archive_read_support_filter_lzop.c @@ -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); diff --git a/libarchive/archive_read_support_filter_program.c b/libarchive/archive_read_support_filter_program.c index 1ba63b5d6..855403872 100644 --- a/libarchive/archive_read_support_filter_program.c +++ b/libarchive/archive_read_support_filter_program.c @@ -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); } diff --git a/libarchive/archive_read_support_filter_rpm.c b/libarchive/archive_read_support_filter_rpm.c index 43b6a2e52..63f288271 100644 --- a/libarchive/archive_read_support_filter_rpm.c +++ b/libarchive/archive_read_support_filter_rpm.c @@ -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); } diff --git a/libarchive/archive_read_support_filter_uu.c b/libarchive/archive_read_support_filter_uu.c index 30e51f9b8..46dcc037e 100644 --- a/libarchive/archive_read_support_filter_uu.c +++ b/libarchive/archive_read_support_filter_uu.c @@ -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); } diff --git a/libarchive/archive_read_support_filter_xz.c b/libarchive/archive_read_support_filter_xz.c index 86b7aafbc..acb6b012d 100644 --- a/libarchive/archive_read_support_filter_xz.c +++ b/libarchive/archive_read_support_filter_xz.c @@ -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 diff --git a/libarchive/archive_read_support_filter_zstd.c b/libarchive/archive_read_support_filter_zstd.c index e40db9f0d..a1c39d8a0 100644 --- a/libarchive/archive_read_support_filter_zstd.c +++ b/libarchive/archive_read_support_filter_zstd.c @@ -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