summaryrefslogtreecommitdiff
path: root/lib/fstream/uncompress
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-06-04 12:16:55 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-06-04 12:16:55 +0200
commitabcdc94c9939d6b085e2b76f76817df9be5fe2cc (patch)
tree290bd5e923cbdb5aef978ba5c9edb8ed65ff44da /lib/fstream/uncompress
parent08612cbb353fca3f4cac1ae0a004d76f73ef878e (diff)
Fix: allow concatenated Bzip2 streams
This is a followup to dd4e6ead142e58568aec89d76b0b2e867ee983f2. Basically the same problem occours with Bzip2, but it so far it wasn't possible to find a sampel that reproduces it. Unlike libxz, the libbz2 API does not support concatenated streams by itself and will choke when trying to decompress after the stream end, so this commit adds a workaround to simply initialize the decompressor on-the-fly and tear it down again when and end-of-stream is returned. The end-of-file condition is only set when there actually is no more data to read. Otherwise, the decompressor will be re-initialized in the next round. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/fstream/uncompress')
-rw-r--r--lib/fstream/uncompress/bzip2.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/lib/fstream/uncompress/bzip2.c b/lib/fstream/uncompress/bzip2.c
index b5fae5c..429950a 100644
--- a/lib/fstream/uncompress/bzip2.c
+++ b/lib/fstream/uncompress/bzip2.c
@@ -11,6 +11,7 @@
typedef struct {
istream_comp_t base;
+ bool initialized;
bz_stream strm;
} istream_bzip2_t;
@@ -21,6 +22,17 @@ static int precache(istream_t *base)
int ret;
for (;;) {
+ if (!bzip2->initialized) {
+ if (BZ2_bzDecompressInit(&bzip2->strm, 0, 0) != BZ_OK) {
+ fprintf(stderr, "%s: error initializing "
+ "bzip2 decompressor.\n",
+ wrapped->get_filename(wrapped));
+ return -1;
+ }
+
+ bzip2->initialized = true;
+ }
+
ret = istream_precache(wrapped);
if (ret != 0)
return ret;
@@ -48,8 +60,16 @@ static int precache(istream_t *base)
bzip2->strm.avail_in;
if (ret == BZ_STREAM_END) {
- base->eof = true;
- break;
+ if (istream_precache(wrapped))
+ return -1;
+
+ BZ2_bzDecompressEnd(&bzip2->strm);
+ bzip2->initialized = false;
+
+ if (wrapped->buffer_used == 0) {
+ base->eof = true;
+ break;
+ }
}
}
@@ -60,7 +80,8 @@ static void cleanup(istream_comp_t *base)
{
istream_bzip2_t *bzip2 = (istream_bzip2_t *)base;
- BZ2_bzDecompressEnd(&bzip2->strm);
+ if (bzip2->initialized)
+ BZ2_bzDecompressEnd(&bzip2->strm);
}
istream_comp_t *istream_bzip2_create(const char *filename)
@@ -74,13 +95,6 @@ istream_comp_t *istream_bzip2_create(const char *filename)
return NULL;
}
- if (BZ2_bzDecompressInit(&bzip2->strm, 0, 0) != BZ_OK) {
- fprintf(stderr, "%s: error initializing bzip2 decompressor.\n",
- filename);
- free(bzip2);
- return NULL;
- }
-
((istream_t *)base)->precache = precache;
base->cleanup = cleanup;
return base;