Explorar o código

tar: Fix path encoding conversion error messages

Since commit 71c981a213 (Encoding: Fix potential encoding issues with
libarchive on Windows, 2014-06-12, v3.1.0-rc1~350^2) we use libarchive's
wide character APIs for entry paths.  This works well on Windows where
this conversion expects UTF-8 and produces UTF-16.  However, on
non-Windows platforms this conversion expects the locale's encoding.

Under `LANG=C` conversion may fail on paths using encodings such as
UTF-8, but we've been ignoring `ToWide` failure and passing empty paths
to libarchive.  This causes incomplete diagnostics like "Can't lstat".

Restore use of libarchive's narrow APIs on non-Windows platforms.  This
defers encoding conversions to libarchive, enabling better diagnostics
like "Can't translate Pathname '...' to UTF-8".

Issue: #26903
Brad King hai 1 mes
pai
achega
1e54c23568
Modificáronse 2 ficheiros con 26 adicións e 2 borrados
  1. 11 1
      Source/cmArchiveWrite.cxx
  2. 15 1
      Source/cmSystemTools.cxx

+ 11 - 1
Source/cmArchiveWrite.cxx

@@ -17,7 +17,9 @@
 #include <cm3p/archive_entry.h>
 
 #include "cmsys/Directory.hxx"
-#include "cmsys/Encoding.hxx"
+#ifdef _WIN32
+#  include "cmsys/Encoding.hxx"
+#endif
 #include "cmsys/FStream.hxx"
 
 #include "cm_parse_date.h"
@@ -40,14 +42,22 @@ static std::string cm_archive_error_string(struct archive* a)
 static void cm_archive_entry_copy_pathname(struct archive_entry* e,
                                            std::string const& dest)
 {
+#ifdef _WIN32
   archive_entry_copy_pathname_w(e, cmsys::Encoding::ToWide(dest).c_str());
+#else
+  archive_entry_copy_pathname(e, dest.c_str());
+#endif
 }
 
 // Set path used for filesystem access.
 static void cm_archive_entry_copy_sourcepath(struct archive_entry* e,
                                              std::string const& file)
 {
+#ifdef _WIN32
   archive_entry_copy_sourcepath_w(e, cmsys::Encoding::ToWide(file).c_str());
+#else
+  archive_entry_copy_sourcepath(e, file.c_str());
+#endif
 }
 
 class cmArchiveWrite::Entry

+ 15 - 1
Source/cmSystemTools.cxx

@@ -99,7 +99,9 @@
 #include <fcntl.h>
 
 #include "cmsys/Directory.hxx"
-#include "cmsys/Encoding.hxx"
+#ifdef _WIN32
+#  include "cmsys/Encoding.hxx"
+#endif
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/System.h"
@@ -379,15 +381,27 @@ extern char** environ; // NOLINT(readability-redundant-declaration)
 // Get path that was read from the archive.
 static std::string cm_archive_entry_pathname(struct archive_entry* entry)
 {
+#  ifdef _WIN32
   return cmsys::Encoding::ToNarrow(archive_entry_pathname_w(entry));
+#  else
+  std::string pathname;
+  if (char const* p = archive_entry_pathname(entry)) {
+    pathname = p;
+  }
+  return pathname;
+#  endif
 }
 
 // Open archive file for reading.
 static int cm_archive_read_open_filename(struct archive* a, char const* file,
                                          int block_size)
 {
+#  ifdef _WIN32
   std::wstring wfile = cmsys::Encoding::ToWide(file);
   return archive_read_open_filename_w(a, wfile.c_str(), block_size);
+#  else
+  return archive_read_open_filename(a, file, block_size);
+#  endif
 }
 #endif