Merge pull request #3346 from stoeckmann/append_filter_desync
Always attach filter to correct bidder
This commit is contained in:
18 files changed
+92
-70
No files matched your search
@@ -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 \
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user