Merge pull request #3346 from stoeckmann/append_filter_desync

Always attach filter to correct bidder
This commit is contained in:
Dustin L. Howett authored and GitHub committed 2026-08-03 12:48:35 -05:00
commit d83294359b
18 files changed
+92 -70

No files matched your search

+1
View File
@@ -404,6 +404,7 @@ libarchive_test_SOURCES= \
libarchive/test/test_archive_pathmatch_oob.c \
libarchive/test/test_archive_read.c \
libarchive/test/test_archive_read_add_passphrase.c \
libarchive/test/test_archive_read_append_filter.c \
libarchive/test/test_archive_read_close_twice.c \
libarchive/test/test_archive_read_multiple_data_objects.c \
libarchive/test/test_archive_read_next_header_empty.c \
-2
View File
@@ -1290,7 +1290,6 @@ __archive_read_register_format(struct archive_read *a,
int
__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;
@@ -1307,7 +1306,6 @@ __archive_read_register_bidder(struct archive_read *a,
memset(a->bidders + i, 0, sizeof(a->bidders[0]));
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,
+22 -51
View File
@@ -33,14 +33,25 @@
#include "archive_private.h"
#include "archive_read_private.h"
static struct archive_read_filter_bidder *
get_last_bidder(struct archive_read *a)
{
size_t i;
for (i = 0; i < sizeof(a->bidders) / sizeof(a->bidders[0]); i++)
{
if (a->bidders[i].vtable == NULL)
break;
}
return a->bidders + (i - 1);
}
int
archive_read_append_filter(struct archive *_a, int code)
{
int r1, r2, number_bidders, i;
const char *str;
struct archive_read_filter_bidder *b;
struct archive_read_filter *f;
struct archive_read *a = (struct archive_read *)_a;
int r1, r2;
r2 = (ARCHIVE_OK);
switch (code)
@@ -53,15 +64,12 @@ archive_read_append_filter(struct archive *_a, int code)
r1 = (ARCHIVE_OK);
break;
case ARCHIVE_FILTER_GZIP:
str = "gzip";
r1 = archive_read_support_filter_gzip(_a);
break;
case ARCHIVE_FILTER_BZIP2:
str = "bzip2";
r1 = archive_read_support_filter_bzip2(_a);
break;
case ARCHIVE_FILTER_COMPRESS:
str = "compress (.Z)";
r1 = archive_read_support_filter_compress(_a);
break;
case ARCHIVE_FILTER_PROGRAM:
@@ -69,43 +77,33 @@ archive_read_append_filter(struct archive *_a, int code)
"Cannot append program filter using archive_read_append_filter");
return (ARCHIVE_FATAL);
case ARCHIVE_FILTER_LZMA:
str = "lzma";
r1 = archive_read_support_filter_lzma(_a);
break;
case ARCHIVE_FILTER_XZ:
str = "xz";
r1 = archive_read_support_filter_xz(_a);
break;
case ARCHIVE_FILTER_UU:
str = "uu";
r1 = archive_read_support_filter_uu(_a);
break;
case ARCHIVE_FILTER_RPM:
str = "rpm";
r1 = archive_read_support_filter_rpm(_a);
break;
case ARCHIVE_FILTER_LZ4:
str = "lz4";
r1 = archive_read_support_filter_lz4(_a);
break;
case ARCHIVE_FILTER_ZSTD:
str = "zstd";
r1 = archive_read_support_filter_zstd(_a);
break;
case ARCHIVE_FILTER_LZIP:
str = "lzip";
r1 = archive_read_support_filter_lzip(_a);
break;
case ARCHIVE_FILTER_LZOP:
str = "lzop";
r1 = archive_read_support_filter_lzop(_a);
break;
case ARCHIVE_FILTER_LRZIP:
str = "lrzip";
r1 = archive_read_support_filter_lrzip(_a);
break;
case ARCHIVE_FILTER_GRZIP:
str = "grzip";
r1 = archive_read_support_filter_grzip(_a);
break;
default:
@@ -114,22 +112,10 @@ archive_read_append_filter(struct archive *_a, int code)
return (ARCHIVE_FATAL);
}
if (code != ARCHIVE_FILTER_NONE)
if (r1 > ARCHIVE_FATAL && code != ARCHIVE_FILTER_NONE)
{
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
b = a->bidders;
for (i = 1; i < number_bidders; i++, b++)
{
if (!b->name || !strcmp(b->name, str))
break;
}
if (!b->name || strcmp(b->name, str))
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Internal error: Unable to append filter");
return (ARCHIVE_FATAL);
}
struct archive_read_filter_bidder *b;
struct archive_read_filter *f;
f = calloc(1, sizeof(*f));
if (f == NULL)
@@ -137,6 +123,7 @@ archive_read_append_filter(struct archive *_a, int code)
archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL);
}
b = get_last_bidder(a);
f->bidder = b;
f->archive = a;
f->upstream = a->filter;
@@ -162,37 +149,22 @@ int
archive_read_append_filter_program_signature(struct archive *_a,
const char *cmd, const void *signature, size_t signature_len)
{
int r, number_bidders, i;
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter_bidder *b;
struct archive_read_filter *f;
struct archive_read *a = (struct archive_read *)_a;
int r;
if (archive_read_support_filter_program_signature(_a, cmd, signature,
signature_len) != (ARCHIVE_OK))
return (ARCHIVE_FATAL);
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
b = a->bidders;
for (i = 0; i < number_bidders; i++, b++)
{
/* Program bidder name set to filter name after initialization */
if (b->data && !b->name)
break;
}
if (!b->data)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Internal error: Unable to append program filter");
return (ARCHIVE_FATAL);
}
f = calloc(1, sizeof(*f));
if (f == NULL)
{
archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL);
}
b = get_last_bidder(a);
f->bidder = b;
f->archive = a;
f->upstream = a->filter;
@@ -202,7 +174,6 @@ archive_read_append_filter_program_signature(struct archive *_a,
__archive_read_free_filters(a);
return (ARCHIVE_FATAL);
}
b->name = a->filter->name;
a->bypass_filter_bidding = 1;
return r;
-3
View File
@@ -68,8 +68,6 @@ struct archive_read_filter_bidder_vtable {
struct archive_read_filter_bidder {
/* Configuration data for the bidder. */
void *data;
/* Name of the filter */
const char *name;
const struct archive_read_filter_bidder_vtable *vtable;
};
@@ -250,7 +248,6 @@ int __archive_read_register_format(struct archive_read *a,
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 *);
@@ -91,7 +91,7 @@ archive_read_support_filter_bzip2(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "bzip2",
if (__archive_read_register_bidder(a, NULL,
&bzip2_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -160,7 +160,7 @@ archive_read_support_filter_compress(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
return __archive_read_register_bidder(a, NULL, "compress (.Z)",
return __archive_read_register_bidder(a, NULL,
&compress_bidder_vtable);
}
@@ -62,7 +62,7 @@ archive_read_support_filter_grzip(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "grzip",
if (__archive_read_register_bidder(a, NULL,
&grzip_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -96,7 +96,7 @@ archive_read_support_filter_gzip(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "gzip",
if (__archive_read_register_bidder(a, NULL,
&gzip_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -61,7 +61,7 @@ archive_read_support_filter_lrzip(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "lrzip",
if (__archive_read_register_bidder(a, NULL,
&lrzip_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
+1 -1
View File
@@ -118,7 +118,7 @@ archive_read_support_filter_lz4(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "lz4",
if (__archive_read_register_bidder(a, NULL,
&lz4_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -109,7 +109,7 @@ archive_read_support_filter_lzop(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "lzop",
if (__archive_read_register_bidder(a, NULL,
&lzop_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -156,7 +156,7 @@ archive_read_support_filter_program_signature(struct archive *_a,
memcpy(state->signature, signature, signature_len);
}
if (__archive_read_register_bidder(a, state, NULL,
if (__archive_read_register_bidder(a, state,
&program_bidder_vtable) != ARCHIVE_OK) {
free_state(state);
return (ARCHIVE_FATAL);
+1 -1
View File
@@ -71,7 +71,7 @@ archive_read_support_filter_rpm(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
return __archive_read_register_bidder(a, NULL, "rpm",
return __archive_read_register_bidder(a, NULL,
&rpm_bidder_vtable);
}
+1 -1
View File
@@ -92,7 +92,7 @@ archive_read_support_filter_uu(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
return __archive_read_register_bidder(a, NULL, "uu",
return __archive_read_register_bidder(a, NULL,
&uudecode_bidder_vtable);
}
+3 -3
View File
@@ -115,7 +115,7 @@ archive_read_support_filter_xz(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "xz",
if (__archive_read_register_bidder(a, NULL,
&xz_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -147,7 +147,7 @@ archive_read_support_filter_lzma(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "lzma",
if (__archive_read_register_bidder(a, NULL,
&lzma_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -180,7 +180,7 @@ archive_read_support_filter_lzip(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "lzip",
if (__archive_read_register_bidder(a, NULL,
&lzip_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -87,7 +87,7 @@ archive_read_support_filter_zstd(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
if (__archive_read_register_bidder(a, NULL, "zstd",
if (__archive_read_register_bidder(a, NULL,
&zstd_bidder_vtable) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
+1
View File
@@ -33,6 +33,7 @@ IF(ENABLE_TEST)
test_archive_pathmatch_oob.c
test_archive_read.c
test_archive_read_add_passphrase.c
test_archive_read_append_filter.c
test_archive_read_close_twice.c
test_archive_read_multiple_data_objects.c
test_archive_read_next_header_empty.c
@@ -0,0 +1,54 @@
/*-
* Copyright (c) 2026 Tobias Stoeckmann
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive.h"
#include "test.h"
DEFINE_TEST(test_archive_read_append_filter)
{
struct archive *a;
int r;
a = archive_read_new();
assert(a != NULL);
/* Append a program bidder (without filter). */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_filter_program(a, "prog1"));
/* Append a filter program which comes with its own bidder. */
r = archive_read_append_filter_program(a, "prog2");
/* Verify that filter uses its own bidder. */
if (r == ARCHIVE_FATAL) {
assertEqualStringA(a, "Can't initialize filter; unable to run program \"prog2\"",
archive_error_string(a));
} else {
assertEqualIntA(a, ARCHIVE_OK, r);
assertEqualStringA(a, "Program: prog2", archive_filter_name(a, 0));
}
archive_read_free(a);
}