]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
reader: introduce archive_read_filter_bidder::vtable
authorEmil Velikov <emil.l.velikov@gmail.com>
Sat, 14 Mar 2020 15:47:22 +0000 (15:47 +0000)
committerEmil Velikov <emil.l.velikov@gmail.com>
Sat, 23 Oct 2021 18:26:23 +0000 (19:26 +0100)
Provides a clear separation between RW data and RO executable code.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
15 files changed:
libarchive/archive_read.c
libarchive/archive_read_append_filter.c
libarchive/archive_read_private.h
libarchive/archive_read_support_filter_bzip2.c
libarchive/archive_read_support_filter_compress.c
libarchive/archive_read_support_filter_grzip.c
libarchive/archive_read_support_filter_gzip.c
libarchive/archive_read_support_filter_lrzip.c
libarchive/archive_read_support_filter_lz4.c
libarchive/archive_read_support_filter_lzop.c
libarchive/archive_read_support_filter_program.c
libarchive/archive_read_support_filter_rpm.c
libarchive/archive_read_support_filter_uu.c
libarchive/archive_read_support_filter_xz.c
libarchive/archive_read_support_filter_zstd.c

index 01dcd5f1e6fc4804a1bcbfbd9b475b3e50b43a86..cf97524b35a151791aeba309529fc1e67f322571 100644 (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,
index da7c55b9b0880dd4f66013f7a756b43be04fdb8a..25dc4b2a2b7f6febe4920e9cd77f8c0f730c6fd6 100644 (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);
index 539aae8ca2c9b9d9ff7917900002fe4f5fa18cad..b3cee971e2dd5e641fccb44fe5e7a007b398f59a 100644 (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;
 };
 
 /*
index 3dd1f1defce0835fbdef8273c9cec8815c5fdac7..b944570928c31a304b93388b9159586795856f3c 100644 (file)
@@ -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
index 166b145c7c03f28b637dfce10a354816e1eca734..44a0fc8ec6936d1771ea998b18dd57d698de8d63 100644 (file)
@@ -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);
 }
 
index 782720ca5e2040b0b8382286b0f134345632067d..20fb18ae23838b5b5b36ef59c39a0feba57630a5 100644 (file)
@@ -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");
index 67b9a955087ec27c4b01d68492b868e1dfe022f5..221b78ae0d74fbfba5877e273fa352792bf0b39d 100644 (file)
@@ -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);
index 81bbec253ca78e4dede4fca8ded11b9356b28a43..77dae4b3dd4761e141f0a7cf6c456acb1f2f6edb 100644 (file)
@@ -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");
index cfa6870eec709327979a2edb1008281694aba59e..eb8ee49167faa0b2fc4113fd44aef8c76696ee43 100644 (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
index a2846b8248bbbeeca0eeccca1f016cb188bbd630..e231306ad4e7713fbb561de8bae0ef28be23b483 100644 (file)
@@ -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);
index 1ba63b5d63097a063706d7cb4f226a0a8407cc73..855403872ef956c11da576791eb5342789b51b4d 100644 (file)
@@ -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);
 }
 
index 43b6a2e5211ee6f40b87fcf46f7deaafe2846409..63f288271a11e9a958f9b0595f6824c2f3ccd717 100644 (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);
 }
 
index 30e51f9b8b112d6af4606acd3e4908e61b5cf3ed..46dcc037e4d48fb71fe5f933fd4c93df2c5ddfe6 100644 (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);
 }
 
index 86b7aafbcad78670b34cd99eead82bc99a70af41..acb6b012d411987e8ae67da55d5101315a8d7395 100644 (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
index e40db9f0ddff986824f7bc4420995f4aa7816ea4..a1c39d8a0ae0a260353c2779011144f587a49e7f 100644 (file)
@@ -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