From: Dag-Erling Smørgrav Date: Mon, 8 Sep 2025 20:17:09 +0000 (+0200) Subject: archive_write: Set archive state to fatal if format or filters fail X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4768f3853590cd8a9af130dac0b9561253e01a67;p=thirdparty%2Flibarchive.git archive_write: Set archive state to fatal if format or filters fail In archive_write_header(), if the format method or a filter flush method fails, we set the archive state to fatal, but we did not do this in archive_write_data() or archive_write_finish_entry(). There is no good reason for this discrepancy. Not setting the archive state to fatal means a subsequent archive_write_free() will invoke archive_write_close() which may retry the operation and cause archive_write_free() to return an unexpected ARCHIVE_FATAL. --- diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c index 292f719df..9b9cb196f 100644 --- a/libarchive/archive_write.c +++ b/libarchive/archive_write.c @@ -806,7 +806,10 @@ _archive_write_finish_entry(struct archive *_a) if (a->archive.state & ARCHIVE_STATE_DATA && a->format_finish_entry != NULL) ret = (a->format_finish_entry)(a); - a->archive.state = ARCHIVE_STATE_HEADER; + if (ret == ARCHIVE_FATAL) + a->archive.state = ARCHIVE_STATE_FATAL; + else + a->archive.state = ARCHIVE_STATE_HEADER; return (ret); } @@ -818,6 +821,7 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s) { struct archive_write *a = (struct archive_write *)_a; const size_t max_write = INT_MAX; + int ret; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_DATA, "archive_write_data"); @@ -825,7 +829,10 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s) if (s > max_write) s = max_write; archive_clear_error(&a->archive); - return ((a->format_write_data)(a, buff, s)); + ret = (a->format_write_data)(a, buff, s); + if (ret == ARCHIVE_FATAL) + a->archive.state = ARCHIVE_STATE_FATAL; + return (ret); } static struct archive_write_filter *