From: Sean Purcell Date: Thu, 20 Apr 2017 17:47:54 +0000 (-0700) Subject: Small zstd fixes X-Git-Tag: v3.3.3~44^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d38f66640aae194c3c055cb24774f00464d52b89;p=thirdparty%2Flibarchive.git Small zstd fixes --- diff --git a/libarchive/archive.h b/libarchive/archive.h index a6f853361..0c750ba65 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -177,6 +177,7 @@ __LA_DECL const char * archive_zlib_version(void); __LA_DECL const char * archive_liblzma_version(void); __LA_DECL const char * archive_bzlib_version(void); __LA_DECL const char * archive_liblz4_version(void); +__LA_DECL const char * archive_libzstd_version(void); /* Declare our basic types. */ struct archive; diff --git a/libarchive/archive_read_support_filter_zstd.c b/libarchive/archive_read_support_filter_zstd.c index 3a8c54054..dc9ceee35 100644 --- a/libarchive/archive_read_support_filter_zstd.c +++ b/libarchive/archive_read_support_filter_zstd.c @@ -60,6 +60,7 @@ struct private_data { unsigned char *out_block; size_t out_block_size; int64_t total_out; + char endFrame; /* True = not in the middle of a zstd frame. */ char eof; /* True = found end of compressed data. */ char in_stream; }; @@ -200,6 +201,8 @@ zstd_bidder_init(struct archive_read_filter *self) self->close = zstd_filter_close; state->in_stream = 0; /* We're not actually within a stream yet. */ + state->eof = 0; + state->endFrame = 1; /* We could end now without corruption */ return (ARCHIVE_OK); } @@ -235,11 +238,20 @@ zstd_filter_read(struct archive_read_filter *self, const void **p) } in.src = __archive_read_filter_ahead(self->upstream, 1, &avail_in); - if (in.src == NULL && avail_in <= 0) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Truncated zstd input"); - return (ARCHIVE_FATAL); + if (avail_in < 0) { + return avail_in; + } + if (in.src == NULL && avail_in == 0) { + if (state->endFrame) { + /* end of stream */ + state->eof = 1; + break; + } else { + archive_set_error(&self->archive->archive, + ARCHIVE_ERRNO_MISC, + "Truncated zstd input"); + return (ARCHIVE_FATAL); + } } in.size = avail_in; in.pos = 0; @@ -257,10 +269,9 @@ zstd_filter_read(struct archive_read_filter *self, const void **p) /* Decompressor made some progress */ __archive_read_filter_consume(self->upstream, in.pos); - /* Found end of the frame */ - if (ret == 0) { - state->eof = 1; - } + /* Need to know if it's the end of the frame, as if input ends + * at any other time it's an error */ + state->endFrame = (ret == 0); } decompressed = out.pos; diff --git a/libarchive/archive_version_details.c b/libarchive/archive_version_details.c index 813f0f3f2..bfb20eab2 100644 --- a/libarchive/archive_version_details.c +++ b/libarchive/archive_version_details.c @@ -45,6 +45,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1 #ifdef HAVE_LZ4_H #include #endif +#ifdef HAVE_ZSTD_H +#include +#endif #include "archive.h" #include "archive_private.h" @@ -59,6 +62,7 @@ archive_version_details(void) const char *liblzma = archive_liblzma_version(); const char *bzlib = archive_bzlib_version(); const char *liblz4 = archive_liblz4_version(); + const char *libzstd = archive_libzstd_version(); if (!init) { archive_string_init(&str); @@ -84,6 +88,10 @@ archive_version_details(void) archive_strcat(&str, " liblz4/"); archive_strcat(&str, liblz4); } + if (libzstd) { + archive_strcat(&str, " libzstd/"); + archive_strcat(&str, libzstd); + } } return str.s; } @@ -131,3 +139,13 @@ archive_liblz4_version(void) return NULL; #endif } + +const char * +archive_libzstd_version(void) +{ +#if HAVE_ZSTD_H && HAVE_LIBZSTD + return ZSTD_VERSION_STRING; +#else + return NULL; +#endif +}