summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuska <martin@matuska.org>2020-01-23 16:13:19 +0100
committerMartin Matuska <martin@matuska.org>2020-01-23 16:13:19 +0100
commitd653d0b38de56f30dab6516d41b9793f6827adfe (patch)
treee167e591b6739dc906cb4ce872203508ad4898a8
parent05a34e47b3ed2bef4d7b6d86fa4d6bbd549c0b4a (diff)
downloadlibarchive-d653d0b38de56f30dab6516d41b9793f6827adfe.tar.gz
XAR writer: fix compression output buffer handling
Add "none" as acceptable value to xar:checksum and xar:toc-checksum Document XAR options in bsdtar(1) Fixes #1317
-rw-r--r--libarchive/archive_write_set_format_xar.c45
-rw-r--r--tar/bsdtar.119
2 files changed, 54 insertions, 10 deletions
diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c
index 2e845f86..ab0c6b48 100644
--- a/libarchive/archive_write_set_format_xar.c
+++ b/libarchive/archive_write_set_format_xar.c
@@ -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);
}
diff --git a/tar/bsdtar.1 b/tar/bsdtar.1
index 7af8f9f7..b95a3314 100644
--- a/tar/bsdtar.1
+++ b/tar/bsdtar.1
@@ -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