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 <emil.l.velikov@gmail.com>
This commit is contained in:
Emil Velikov committed 2021-10-23 19:26:23 +01:00
1 parent 64b82ac5c8
commit 5b5f6b591b
14 files changed
+62 -143

No files matched your search

+19 -3
View File
@@ -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);
}
+4 -2
View File
@@ -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 *,
@@ -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
@@ -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);
}
/*
@@ -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");
@@ -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);
@@ -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");
+2 -8
View File
@@ -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
@@ -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);
@@ -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");
+2 -11
View File
@@ -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
+2 -11
View File
@@ -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] = {
+6 -24
View File
@@ -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
@@ -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