]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
XAR writer: fix compression output buffer handling
authorMartin Matuska <martin@matuska.org>
Thu, 23 Jan 2020 15:13:19 +0000 (16:13 +0100)
committerMartin Matuska <martin@matuska.org>
Thu, 23 Jan 2020 15:13:19 +0000 (16:13 +0100)
Add "none" as acceptable value to xar:checksum and xar:toc-checksum
Document XAR options in bsdtar(1)

Fixes #1317

libarchive/archive_write_set_format_xar.c
tar/bsdtar.1

index 2e845f8668a61293a3eb72c4d9c0566b01d13962..ab0c6b48abe0d865dee235b105bbee9230af9562 100644 (file)
@@ -411,6 +411,8 @@ xar_options(struct archive_write *a, const char *key, const char *value)
        if (strcmp(key, "checksum") == 0) {
                if (value == NULL)
                        xar->opt_sumalg = CKSUM_NONE;
+               else if (strcmp(value, "none") == 0)
+                       xar->opt_sumalg = CKSUM_NONE;
                else if (strcmp(value, "sha1") == 0)
                        xar->opt_sumalg = CKSUM_SHA1;
                else if (strcmp(value, "md5") == 0)
@@ -429,6 +431,8 @@ xar_options(struct archive_write *a, const char *key, const char *value)
 
                if (value == NULL)
                        xar->opt_compression = NONE;
+               else if (strcmp(value, "none") == 0)
+                       xar->opt_compression = NONE;
                else if (strcmp(value, "gzip") == 0)
                        xar->opt_compression = GZIP;
                else if (strcmp(value, "bzip2") == 0)
@@ -482,6 +486,8 @@ xar_options(struct archive_write *a, const char *key, const char *value)
        if (strcmp(key, "toc-checksum") == 0) {
                if (value == NULL)
                        xar->opt_toc_sumalg = CKSUM_NONE;
+               else if (strcmp(value, "none") == 0)
+                       xar->opt_toc_sumalg = CKSUM_NONE;
                else if (strcmp(value, "sha1") == 0)
                        xar->opt_toc_sumalg = CKSUM_SHA1;
                else if (strcmp(value, "md5") == 0)
@@ -696,13 +702,37 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s)
                else
                        run = ARCHIVE_Z_FINISH;
                /* Compress file data. */
-               r = compression_code(&(a->archive), &(xar->stream), run);
-               if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
-                       return (ARCHIVE_FATAL);
+               for (;;) {
+                       r = compression_code(&(a->archive), &(xar->stream),
+                           run);
+                       if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
+                               return (ARCHIVE_FATAL);
+                       if (xar->stream.avail_out == 0 ||
+                           run == ARCHIVE_Z_FINISH) {
+                               size = sizeof(xar->wbuff) -
+                                   xar->stream.avail_out;
+                               checksum_update(&(xar->a_sumwrk), xar->wbuff,
+                                   size);
+                               xar->cur_file->data.length += size;
+                               if (write_to_temp(a, xar->wbuff,
+                                   size) != ARCHIVE_OK)
+                                       return (ARCHIVE_FATAL);
+                               if (r == ARCHIVE_OK) {
+                                       /* Output buffer was full */
+                                       xar->stream.next_out = xar->wbuff;
+                                       xar->stream.avail_out =
+                                           sizeof(xar->wbuff);
+                               } else {
+                                       /* ARCHIVE_EOF - We are done */
+                                       break;
+                               }
+                       } else {
+                               /* Compressor wants more input */
+                               break;
+                       }
+               }
                rsize = s - xar->stream.avail_in;
                checksum_update(&(xar->e_sumwrk), buff, rsize);
-               size = sizeof(xar->wbuff) - xar->stream.avail_out;
-               checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
        }
 #if !defined(_WIN32) || defined(__CYGWIN__)
        if (xar->bytes_remaining ==
@@ -739,12 +769,9 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s)
        if (xar->cur_file->data.compression == NONE) {
                if (write_to_temp(a, buff, size) != ARCHIVE_OK)
                        return (ARCHIVE_FATAL);
-       } else {
-               if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
-                       return (ARCHIVE_FATAL);
+               xar->cur_file->data.length += size;
        }
        xar->bytes_remaining -= rsize;
-       xar->cur_file->data.length += size;
 
        return (rsize);
 }
index 7af8f9f7d39ece2bd5add7672a793c8130086b38..b95a33145704856ea8229da30c3c951f6f5bd749 100644 (file)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 20, 2020
+.Dd January 23, 2020
 .Dt TAR 1
 .Os
 .Sh NAME
@@ -650,6 +650,23 @@ lines in the output.
 .It Cm mtree:indent
 Produce human-readable output by indenting options and splitting lines
 to fit into 80 columns.
+.It Cm xar:checksum Ns = Ns Ar type
+Use
+.Ar type
+as file checksum method.
+Supported values are none, md5 and sha1 (default).
+.It Cm xar:compression Ns = Ns Ar type
+Use
+.Ar type
+as compression method.
+Supported values are none, bzip2, gzip (default), lzma and xz.
+.It Cm xar:compression_level
+A decimal integer from 1 to 9 specifying the compression level.
+.It Cm xar:toc-checksum Ns = Ns Ar type
+Use
+.Ar type
+as table of contents checksum method.
+Supported values are none, md5 and sha1 (default).
 .It Cm zip:compression Ns = Ns Ar type
 Use
 .Ar type