From: Emil Velikov Date: Sat, 23 Oct 2021 17:22:05 +0000 (+0100) Subject: reader: transform get_bidder into register_bidder X-Git-Tag: v3.6.0~18^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b5f6b591bced6037959945f69ab46466abd1698;p=thirdparty%2Flibarchive.git reader: transform get_bidder into register_bidder There's a notable duplication across all the read bidder code. Check the archive magic/state, set the bidder private data (to NULL in all but one case), name and vtable. Change the helper to do the actual registration, keeping things simpler in the dozen+ filters. This also allows us to enforce the bidder ::bid and ::init dispatch are non NULL. The final one ::free is optional. NOTE: some of the bidders do _not_ set a name, which I suspect is a pre-existing bug. I've left them as-is, but we might want to fix and enforce that somehow. Signed-off-by: Emil Velikov --- diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c index cf97524b3..527aebb10 100644 --- a/libarchive/archive_read.c +++ b/libarchive/archive_read.c @@ -1231,18 +1231,34 @@ __archive_read_register_format(struct archive_read *a, * initialization functions. */ int -__archive_read_get_bidder(struct archive_read *a, - struct archive_read_filter_bidder **bidder) +__archive_read_register_bidder(struct archive_read *a, + void *bidder_data, + const char *name, + const struct archive_read_filter_bidder_vtable *vtable) { + struct archive_read_filter_bidder *bidder; int i, number_slots; + archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "__archive_read_register_bidder"); + number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]); for (i = 0; i < number_slots; i++) { if (a->bidders[i].vtable != NULL) continue; memset(a->bidders + i, 0, sizeof(a->bidders[0])); - *bidder = (a->bidders + i); + bidder = (a->bidders + i); + bidder->data = bidder_data; + bidder->name = name; + bidder->vtable = vtable; + if (bidder->vtable->bid == NULL || bidder->vtable->init == NULL) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, + "Internal error: " + "no bid/init for filter bidder"); + return (ARCHIVE_FATAL); + } + return (ARCHIVE_OK); } diff --git a/libarchive/archive_read_private.h b/libarchive/archive_read_private.h index b3cee971e..ff6c336c9 100644 --- a/libarchive/archive_read_private.h +++ b/libarchive/archive_read_private.h @@ -243,8 +243,10 @@ int __archive_read_register_format(struct archive_read *a, int (*format_capabilities)(struct archive_read *), int (*has_encrypted_entries)(struct archive_read *)); -int __archive_read_get_bidder(struct archive_read *a, - struct archive_read_filter_bidder **bidder); +int __archive_read_register_bidder(struct archive_read *a, + void *bidder_data, + const char *name, + const struct archive_read_filter_bidder_vtable *vtable); const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *); const void *__archive_read_filter_ahead(struct archive_read_filter *, diff --git a/libarchive/archive_read_support_filter_bzip2.c b/libarchive/archive_read_support_filter_bzip2.c index b94457092..52537d855 100644 --- a/libarchive/archive_read_support_filter_bzip2.c +++ b/libarchive/archive_read_support_filter_bzip2.c @@ -90,17 +90,11 @@ int archive_read_support_filter_bzip2(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *reader; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_bzip2"); - - if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "bzip2", + &bzip2_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - reader->data = NULL; - reader->name = "bzip2"; - 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 44a0fc8ec..36a708a15 100644 --- a/libarchive/archive_read_support_filter_compress.c +++ b/libarchive/archive_read_support_filter_compress.c @@ -159,18 +159,9 @@ int archive_read_support_filter_compress(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_compress"); - - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - bidder->data = NULL; - bidder->name = "compress (.Z)"; - bidder->vtable = &compress_bidder_vtable; - return (ARCHIVE_OK); + return __archive_read_register_bidder(a, NULL, "compress (.Z)", + &compress_bidder_vtable); } /* diff --git a/libarchive/archive_read_support_filter_grzip.c b/libarchive/archive_read_support_filter_grzip.c index 20fb18ae2..d4d1737cd 100644 --- a/libarchive/archive_read_support_filter_grzip.c +++ b/libarchive/archive_read_support_filter_grzip.c @@ -64,16 +64,11 @@ int archive_read_support_filter_grzip(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *reader; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_grzip"); - - if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, NULL, + &grzip_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - reader->data = 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 221b78ae0..49bd46920 100644 --- a/libarchive/archive_read_support_filter_gzip.c +++ b/libarchive/archive_read_support_filter_gzip.c @@ -104,17 +104,11 @@ int archive_read_support_filter_gzip(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_gzip"); - - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "gzip", + &gzip_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "gzip"; - 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 77dae4b3d..a2389894f 100644 --- a/libarchive/archive_read_support_filter_lrzip.c +++ b/libarchive/archive_read_support_filter_lrzip.c @@ -63,17 +63,11 @@ int archive_read_support_filter_lrzip(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *reader; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_lrzip"); - - if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "lrzip", + &lrzip_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - reader->data = NULL; - reader->name = "lrzip"; - 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 eb8ee4916..8d44d30a7 100644 --- a/libarchive/archive_read_support_filter_lz4.c +++ b/libarchive/archive_read_support_filter_lz4.c @@ -116,17 +116,11 @@ int archive_read_support_filter_lz4(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *reader; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_lz4"); - - if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "lz4", + &lz4_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - reader->data = NULL; - reader->name = "lz4"; - 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 e231306ad..971f04ebf 100644 --- a/libarchive/archive_read_support_filter_lzop.c +++ b/libarchive/archive_read_support_filter_lzop.c @@ -111,16 +111,11 @@ int archive_read_support_filter_lzop(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *reader; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_lzop"); - - if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, NULL, + &lzop_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - reader->data = 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 855403872..5d9d07192 100644 --- a/libarchive/archive_read_support_filter_program.c +++ b/libarchive/archive_read_support_filter_program.c @@ -130,39 +130,13 @@ program_bidder_vtable = { .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) -{ - - if (signature != NULL && signature_len > 0) { - state->signature_len = signature_len; - state->signature = malloc(signature_len); - memcpy(state->signature, signature, signature_len); - } - - /* - * Fill in the bidder object. - */ - bidder->data = state; - bidder->vtable = &program_bidder_vtable; - return (ARCHIVE_OK); -} - int archive_read_support_filter_program_signature(struct archive *_a, const char *cmd, const void *signature, size_t signature_len) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; struct program_bidder *state; - /* - * Get a bidder object from the read core. - */ - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - /* * Allocate our private state. */ @@ -173,7 +147,19 @@ archive_read_support_filter_program_signature(struct archive *_a, if (state->cmd == NULL) goto memerr; - return set_bidder_signature(bidder, state, signature, signature_len); + if (signature != NULL && signature_len > 0) { + state->signature_len = signature_len; + state->signature = malloc(signature_len); + memcpy(state->signature, signature, signature_len); + } + + if (__archive_read_register_bidder(a, state, NULL, + &program_bidder_vtable) != ARCHIVE_OK) { + free_state(state); + return (ARCHIVE_FATAL); + } + return (ARCHIVE_OK); + memerr: free_state(state); archive_set_error(_a, ENOMEM, "Can't allocate memory"); diff --git a/libarchive/archive_read_support_filter_rpm.c b/libarchive/archive_read_support_filter_rpm.c index 63f288271..73107e868 100644 --- a/libarchive/archive_read_support_filter_rpm.c +++ b/libarchive/archive_read_support_filter_rpm.c @@ -82,18 +82,9 @@ int archive_read_support_filter_rpm(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_rpm"); - - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - bidder->data = NULL; - bidder->name = "rpm"; - bidder->vtable = &rpm_bidder_vtable; - return (ARCHIVE_OK); + return __archive_read_register_bidder(a, NULL, "rpm", + &rpm_bidder_vtable); } static int diff --git a/libarchive/archive_read_support_filter_uu.c b/libarchive/archive_read_support_filter_uu.c index 46dcc037e..7a6da6a10 100644 --- a/libarchive/archive_read_support_filter_uu.c +++ b/libarchive/archive_read_support_filter_uu.c @@ -86,18 +86,9 @@ int archive_read_support_filter_uu(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_uu"); - - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - bidder->data = NULL; - bidder->name = "uu"; - bidder->vtable = &uudecode_bidder_vtable; - return (ARCHIVE_OK); + return __archive_read_register_bidder(a, NULL, "uu", + &uudecode_bidder_vtable); } static const unsigned char ascii[256] = { diff --git a/libarchive/archive_read_support_filter_xz.c b/libarchive/archive_read_support_filter_xz.c index acb6b012d..f557377f2 100644 --- a/libarchive/archive_read_support_filter_xz.c +++ b/libarchive/archive_read_support_filter_xz.c @@ -118,17 +118,11 @@ int archive_read_support_filter_xz(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_xz"); - - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "xz", + &xz_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "xz"; - bidder->vtable = &xz_bidder_vtable; #if HAVE_LZMA_H && HAVE_LIBLZMA return (ARCHIVE_OK); #else @@ -156,17 +150,11 @@ int archive_read_support_filter_lzma(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_lzma"); - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "lzma", + &lzma_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "lzma"; - bidder->vtable = &lzma_bidder_vtable; #if HAVE_LZMA_H && HAVE_LIBLZMA return (ARCHIVE_OK); #else @@ -195,17 +183,11 @@ int archive_read_support_filter_lzip(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_lzip"); - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "lzip", + &lzip_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "lzip"; - 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 a1c39d8a0..b4528b35f 100644 --- a/libarchive/archive_read_support_filter_zstd.c +++ b/libarchive/archive_read_support_filter_zstd.c @@ -89,17 +89,11 @@ int archive_read_support_filter_zstd(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_zstd"); - - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "zstd", + &zstd_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "zstd"; - bidder->vtable = &zstd_bidder_vtable; #if HAVE_ZSTD_H && HAVE_LIBZSTD return (ARCHIVE_OK); #else