Merge pull request #2526 from fdegros/compress_support
Fix SIGSEGV in compress filter when appended before open
(cherry picked from commit 4f3cf235e3)
This commit is contained in:
1 parent
0f9f5c8871
commit
ba5d675183
2 files changed
+185
-3
No files matched your search
@@ -104,6 +104,7 @@ struct private_data {
|
||||
void *out_block;
|
||||
|
||||
/* Decompression status variables. */
|
||||
int initialized;
|
||||
int use_reset_code;
|
||||
int end_of_stream; /* EOF status. */
|
||||
int maxcode; /* Largest code. */
|
||||
@@ -212,7 +213,6 @@ compress_bidder_init(struct archive_read_filter *self)
|
||||
struct private_data *state;
|
||||
static const size_t out_block_size = 64 * 1024;
|
||||
void *out_block;
|
||||
int code;
|
||||
|
||||
self->code = ARCHIVE_FILTER_COMPRESS;
|
||||
self->name = "compress (.Z)";
|
||||
@@ -233,14 +233,23 @@ compress_bidder_init(struct archive_read_filter *self)
|
||||
state->out_block = out_block;
|
||||
self->vtable = &compress_reader_vtable;
|
||||
|
||||
/* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
compress_filter_init(struct archive_read_filter *self)
|
||||
{
|
||||
struct private_data *state = (struct private_data *)self->data;
|
||||
int code;
|
||||
|
||||
state->initialized = 1;
|
||||
|
||||
(void)getbits(self, 8); /* Skip first signature byte. */
|
||||
(void)getbits(self, 8); /* Skip second signature byte. */
|
||||
|
||||
/* Get compression parameters. */
|
||||
code = getbits(self, 8);
|
||||
if ((code & 0x1f) > 16) {
|
||||
if (code < 0 || (code & 0x1f) > 16) {
|
||||
archive_set_error(&self->archive->archive, -1,
|
||||
"Invalid compressed data");
|
||||
return (ARCHIVE_FATAL);
|
||||
@@ -278,6 +287,11 @@ compress_filter_read(struct archive_read_filter *self, const void **pblock)
|
||||
int ret;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
if (!state->initialized) {
|
||||
ret = compress_filter_init(self);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
}
|
||||
if (state->end_of_stream) {
|
||||
*pblock = NULL;
|
||||
return (0);
|
||||
|
||||
@@ -211,6 +211,174 @@ DEFINE_TEST(test_read_append_grzip_filter)
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_compress_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_COMPRESS);
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_bzip2_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_BZIP2);
|
||||
if (r != ARCHIVE_OK && archive_bzlib_version() == NULL && !canBzip2()) {
|
||||
skipping("bzip2 tests require bzlib or working bzip2 command");
|
||||
archive_read_free(a);
|
||||
return;
|
||||
}
|
||||
if (r == ARCHIVE_WARN && canBzip2())
|
||||
assertEqualString(archive_error_string(a), "Using external bzip2 program");
|
||||
else
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_lrzip_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_LRZIP);
|
||||
if (r != ARCHIVE_OK && !canLrzip()) {
|
||||
skipping("lrzip tests require working lrzip command");
|
||||
archive_read_free(a);
|
||||
return;
|
||||
}
|
||||
if (r == ARCHIVE_WARN && canLrzip())
|
||||
assertEqualString(archive_error_string(a), "Using external lrzip program for lrzip decompression");
|
||||
else
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_lz4_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_LZ4);
|
||||
if (r != ARCHIVE_OK && archive_liblz4_version() == NULL && !canLz4()) {
|
||||
skipping("lz4 tests require liblz4 or working lz4 command");
|
||||
archive_read_free(a);
|
||||
return;
|
||||
}
|
||||
if (r == ARCHIVE_WARN && canLz4())
|
||||
assertEqualString(archive_error_string(a), "Using external lz4 program");
|
||||
else
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_lzip_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_LZIP);
|
||||
if (r != ARCHIVE_OK && archive_liblzma_version() == NULL && !canLzip()) {
|
||||
skipping("lzip tests require liblzma or working lzip command");
|
||||
archive_read_free(a);
|
||||
return;
|
||||
}
|
||||
if (r == ARCHIVE_WARN && canLzip())
|
||||
assertEqualString(archive_error_string(a), "Using external lzip program for lzip decompression");
|
||||
else
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_lzma_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_LZMA);
|
||||
if (r != ARCHIVE_OK && archive_liblzma_version() == NULL && !canLzma()) {
|
||||
skipping("lzma tests require liblzma or working lzma command");
|
||||
archive_read_free(a);
|
||||
return;
|
||||
}
|
||||
if (r == ARCHIVE_WARN && canLzma())
|
||||
assertEqualString(archive_error_string(a), "Using external lzma program for lzma decompression");
|
||||
else
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_zstd_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_ZSTD);
|
||||
if (r != ARCHIVE_OK && archive_libzstd_version() == NULL && !canZstd()) {
|
||||
skipping("zstd tests require libzstd or working zstd command");
|
||||
archive_read_free(a);
|
||||
return;
|
||||
}
|
||||
if (r == ARCHIVE_WARN && canZstd())
|
||||
assertEqualString(archive_error_string(a), "Using external zstd program for zstd decompression");
|
||||
else
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_rpm_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_RPM);
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_uu_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_UU);
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_none_filter)
|
||||
{
|
||||
struct archive *a;
|
||||
int r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
|
||||
r = archive_read_append_filter(a, ARCHIVE_FILTER_NONE);
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
archive_read_free(a);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_append_filter_program)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
|
||||
Reference in new issue
Block a user