]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Small zstd fixes
authorSean Purcell <me@seanp.xyz>
Thu, 20 Apr 2017 17:47:54 +0000 (10:47 -0700)
committerSean Purcell <iburinoc@gmail.com>
Tue, 16 May 2017 03:06:48 +0000 (23:06 -0400)
libarchive/archive.h
libarchive/archive_read_support_filter_zstd.c
libarchive/archive_version_details.c

index a6f853361d1d7b01fe8d1c916e2a75271d9a77ed..0c750ba653906f4e4f4d47df74e452ce043c0785 100644 (file)
@@ -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;
index 3a8c54054206d5714a310b30291a6a63b4201ca6..dc9ceee350c0dd8115e9821788813c83cdb1742b 100644 (file)
@@ -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;
index 813f0f3f2e36d4e33d2b8638ab2e3c7f534b4eb1..bfb20eab2027bb755d99a8d4e11d589287f15a74 100644 (file)
@@ -45,6 +45,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
 #ifdef HAVE_LZ4_H
 #include <lz4.h>
 #endif
+#ifdef HAVE_ZSTD_H
+#include <zstd.h>
+#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
+}