From 20fec1520458cdfb71bf1099cfc3648154d57d8f Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Fri, 20 Aug 2021 11:23:20 -0400
Subject: cmArchiveWrite: Check for construction errors on Open

Also update call sites to report the error.

Issue: #19666
---
 Source/CPack/cmCPackDebGenerator.cxx | 24 +++++++++++++++++++++---
 Source/cmArchiveWrite.cxx            |  3 +++
 Source/cmSystemTools.cxx             |  5 ++++-
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 5f0f153..829cef4 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -192,7 +192,13 @@ bool DebGenerator::generateDataTar() const
   cmArchiveWrite data_tar(fileStream_data_tar, this->TarCompressionType,
                           this->DebianArchiveType, 0,
                           static_cast<int>(this->NumThreads));
-  data_tar.Open();
+  if (!data_tar.Open()) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Error opening the archive \""
+                    << filename_data_tar
+                    << "\", ERROR = " << data_tar.GetError() << std::endl);
+    return false;
+  }
 
   // uid/gid should be the one of the root user, and this root user has
   // always uid/gid equal to 0.
@@ -317,7 +323,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
   cmArchiveWrite control_tar(fileStream_control_tar,
                              cmArchiveWrite::CompressGZip,
                              this->DebianArchiveType);
-  control_tar.Open();
+  if (!control_tar.Open()) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Error opening the archive \""
+                    << filename_control_tar
+                    << "\", ERROR = " << control_tar.GetError() << std::endl);
+    return false;
+  }
 
   // sets permissions and uid/gid for the files
   control_tar.SetUIDAndGID(0u, 0u);
@@ -457,7 +469,13 @@ bool DebGenerator::generateDeb() const
   cmGeneratedFileStream debStream;
   debStream.Open(outputPath, false, true);
   cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
-  deb.Open();
+  if (!deb.Open()) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Error opening the archive \""
+                    << outputPath << "\", ERROR = " << deb.GetError()
+                    << std::endl);
+    return false;
+  }
 
   // uid/gid should be the one of the root user, and this root user has
   // always uid/gid equal to 0.
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 54b2998..9e0d80c 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -250,6 +250,9 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
 
 bool cmArchiveWrite::Open()
 {
+  if (!this->Error.empty()) {
+    return false;
+  }
   if (archive_write_open(
         this->Archive, this, nullptr,
         reinterpret_cast<archive_write_callback*>(&Callback::Write),
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index f082ae8..54fe7a1 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1629,7 +1629,10 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
   cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format,
                    compressionLevel);
 
-  a.Open();
+  if (!a.Open()) {
+    cmSystemTools::Error(a.GetError());
+    return false;
+  }
   a.SetMTime(mtime);
   a.SetVerbose(verbose);
   bool tarCreatedSuccessfully = true;
-- 
cgit v0.12