diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst index 21e67cec3e..e940011738 100644 --- a/Help/cpack_gen/archive.rst +++ b/Help/cpack_gen/archive.rst @@ -217,3 +217,15 @@ CPack generators which are essentially archives at their core. These include: It is selected automatically by the archive library backend and not directly set by CMake itself. The default compression level may vary between archive formats, platforms, etc. + +.. variable:: CPACK_ARCHIVE_ENCODING + + .. versionadded:: 4.4 + + Specify the pathname character encoding used in package archives. + + :Default: ``OEM`` + + See the :option:`cmake -E tar ` tool's + :option:`--cmake-tar-encoding ` flag + for supported encoding names. diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 1983168810..d26d0834d2 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -1694,6 +1694,35 @@ Available commands are: not directly set by CMake itself. The default compression level may vary between archive formats, platforms, etc. + .. option:: --cmake-tar-encoding= + + .. versionadded:: 4.4 + + Specify the pathname character encoding used in the archive. + + The ```` may be one of: + + ``UTF-8`` + Archive pathnames are encoded as UTF-8. + + ``OEM`` + On Windows platforms, pathnames are encoded as using the original + equipment manufacturer (OEM) code page. On non-Windows platforms, + pathnames are encoded according to the current locale. + + This is the default value. + + ``UTF-16LE``, ``UTF-16BE`` + Archive pathnames are encoded as UTF-16 little-endian or big-endian. + + ``...`` + Any encoding name supported by ``iconv`` on the current platform. + On Windows, code page names may be specified. + + .. note:: + ``7zip`` archives always encode paths as ``UTF-16LE``, + so this option is silently ignored for that format. + .. option:: --cmake-tar-threads= .. versionadded:: 4.3 diff --git a/Help/release/dev/cmake-E-tar-encoding.rst b/Help/release/dev/cmake-E-tar-encoding.rst new file mode 100644 index 0000000000..30ac5f7ee4 --- /dev/null +++ b/Help/release/dev/cmake-E-tar-encoding.rst @@ -0,0 +1,10 @@ +cmake-E-tar-encoding +-------------------- + +* The :option:`cmake -E tar ` command-line tool gained the + :option:`--cmake-tar-encoding ` flag + to specify the pathname encoding used in archives. + +* The :cpack_gen:`CPack Archive Generator` gained the + :variable:`CPACK_ARCHIVE_ENCODING` variable to specify the pathname + encoding used in package archives. diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 27828f588e..fbec6be96e 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -394,7 +394,7 @@ int cmCPackArchiveGenerator::addOneComponentToArchive( return 0; \ } \ cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat, \ - this->GetCompressionLevel(), \ + this->GetEncoding(), this->GetCompressionLevel(), \ this->GetThreadCount()); \ if (this->UID >= 0 && this->GID >= 0) { \ archive.SetUIDAndGID(this->UID, this->GID); \ @@ -611,3 +611,14 @@ int cmCPackArchiveGenerator::GetCompressionLevel() const return level; } + +std::string cmCPackArchiveGenerator::GetEncoding() const +{ + std::string encoding = "OEM"; + + if (cmValue v = this->GetOptionIfSet("CPACK_ARCHIVE_ENCODING")) { + encoding = *v; + } + + return encoding; +} diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 22c8bba1ee..e295561cc0 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -106,6 +106,7 @@ private: int GetThreadCount() const; int GetCompressionLevel() const; + std::string GetEncoding() const; private: cmArchiveWrite::Compress Compress; diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 0be2ec49b3..585edab34c 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -211,9 +211,9 @@ bool DebGenerator::generateDataTar() const << filename_data_tar << "\" for writing" << std::endl); return false; } - cmArchiveWrite data_tar(fileStream_data_tar, this->TarCompressionType, - this->DebianArchiveType, this->CompressionLevel, - static_cast(this->NumThreads)); + cmArchiveWrite data_tar( + fileStream_data_tar, this->TarCompressionType, this->DebianArchiveType, + "OEM", this->CompressionLevel, static_cast(this->NumThreads)); if (!data_tar.Open()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error opening the archive \"" @@ -344,7 +344,8 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const return false; } cmArchiveWrite control_tar(fileStream_control_tar, this->TarCompressionType, - this->DebianArchiveType, this->CompressionLevel); + this->DebianArchiveType, "OEM", + this->CompressionLevel); if (!control_tar.Open()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error opening the archive \"" diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index a092c655ff..16b6ef46d0 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -96,8 +96,9 @@ struct cmArchiveWrite::Callback }; cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, - std::string const& format, int compressionLevel, - int numThreads) + std::string const& format, + std::string const& encoding, + int compressionLevel, int numThreads) : Stream(os) , Archive(archive_write_new()) , Disk(archive_read_disk_new()) @@ -226,6 +227,20 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, } } + // 7zip always uses UTF16-LE for the headers and doesn't support + // header encoding specification. + // arbsd can use the default encoding of the system only. + if (!is7zip && format != "arbsd" && encoding != "OEM") { + char const* formatForOptions = format == "paxr" ? "pax" : format.c_str(); + if (archive_write_set_format_option(this->Archive, formatForOptions, + "hdrcharset", + encoding.c_str()) != ARCHIVE_OK) { + this->Error = cmStrCat("archive_write_set_format_option(hdrcharset): ", + cm_archive_error_string(this->Archive)); + return; + } + } + if (isFormatSupportsCompressionNatively || compressionLevel != 0) { std::string compressionLevelStr = std::to_string(compressionLevel); std::string archiveFilterName; diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index dac0a57d81..990f4aeab9 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -55,7 +55,8 @@ public: /** Construct with output stream to which to write archive. */ cmArchiveWrite(std::ostream& os, Compress c = CompressNone, - std::string const& format = "paxr", int compressionLevel = 0, + std::string const& format = "paxr", + std::string const& encoding = "OEM", int compressionLevel = 0, int numThreads = 1); ~cmArchiveWrite(); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index ed1516f9a1..862dedf347 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1251,8 +1251,8 @@ std::string cmCTest::Base64GzipEncodeFile(std::string const& file) std::vector files; files.push_back(file); - if (!cmSystemTools::CreateTar(tarFile, files, {}, - cmSystemTools::TarCompressGZip, false)) { + if (!cmSystemTools::CreateTar( + tarFile, files, {}, cmSystemTools::TarCompressGZip, "OEM", false)) { cmCTestLog(this, ERROR_MESSAGE, "Error creating tar while " "encoding file: " diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 16cd19bf8b..8eedc3c375 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -3824,8 +3824,8 @@ bool HandleArchiveCreateCommand(std::vector const& args, if (!cmSystemTools::CreateTar( parsedArgs.Output, parsedArgs.Paths, parsedArgs.WorkingDirectory, - compress, parsedArgs.Verbose, parsedArgs.MTime, parsedArgs.Format, - compressionLevel, threads)) { + compress, "OEM", parsedArgs.Verbose, parsedArgs.MTime, + parsedArgs.Format, compressionLevel, threads)) { status.SetError(cmStrCat("failed to compress: ", parsedArgs.Output)); cmSystemTools::SetFatalErrorOccurred(); return false; @@ -3873,7 +3873,7 @@ bool HandleArchiveExtractCommand(std::vector const& args, std::string inFile = parsedArgs.Input; if (parsedArgs.ListOnly) { - if (!cmSystemTools::ListTar(inFile, parsedArgs.Patterns, + if (!cmSystemTools::ListTar(inFile, parsedArgs.Patterns, "OEM", parsedArgs.Verbose)) { status.SetError(cmStrCat("failed to list: ", inFile)); cmSystemTools::SetFatalErrorOccurred(); @@ -3911,7 +3911,7 @@ bool HandleArchiveExtractCommand(std::vector const& args, inFile, parsedArgs.Patterns, parsedArgs.Touch ? cmSystemTools::cmTarExtractTimestamps::No : cmSystemTools::cmTarExtractTimestamps::Yes, - parsedArgs.Verbose)) { + "OEM", parsedArgs.Verbose)) { status.SetError(cmStrCat("failed to extract:\n ", inFile)); cmSystemTools::SetFatalErrorOccurred(); return false; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 2329449c8b..5f19c911a5 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2359,13 +2359,11 @@ bool cmSystemTools::IsPathToMacOSSharedLibrary(std::string const& path) cmHasLiteralSuffix(path, ".dylib")); } -bool cmSystemTools::CreateTar(std::string const& arFileName, - std::vector const& files, - std::string const& workingDirectory, - cmTarCompression compressType, bool verbose, - std::string const& mtime, - std::string const& format, int compressionLevel, - int numThreads) +bool cmSystemTools::CreateTar( + std::string const& arFileName, std::vector const& files, + std::string const& workingDirectory, cmTarCompression compressType, + std::string const& encoding, bool verbose, std::string const& mtime, + std::string const& format, int compressionLevel, int numThreads) { #if !defined(CMAKE_BOOTSTRAP) cmWorkingDirectory workdir(cmSystemTools::GetLogicalWorkingDirectory()); @@ -2416,7 +2414,7 @@ bool cmSystemTools::CreateTar(std::string const& arFileName, break; } - cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format, + cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format, encoding, compressionLevel, numThreads); if (!a.Open()) { @@ -2440,6 +2438,7 @@ bool cmSystemTools::CreateTar(std::string const& arFileName, #else (void)arFileName; (void)files; + (void)encoding; (void)verbose; return false; #endif @@ -2619,7 +2618,8 @@ bool copy_data(struct archive* ar, struct archive* aw) } bool extract_tar(std::string const& arFileName, - std::vector const& files, bool verbose, + std::vector const& files, + std::string const& encoding, bool verbose, cmSystemTools::cmTarExtractTimestamps extractTimestamps, bool extract) { @@ -2640,6 +2640,15 @@ bool extract_tar(std::string const& arFileName, } archive_read_support_filter_all(a); archive_read_support_format_all(a); + + if (encoding != "OEM") { + if (archive_read_set_options( + a, cmStrCat("hdrcharset=", encoding).c_str()) != ARCHIVE_OK) { + cmSystemTools::Error( + cmStrCat("Cannot set archive encoding: ", encoding)); + return false; + } + } struct archive_entry* entry; struct archive* matching = archive_match_new(); @@ -2749,14 +2758,16 @@ bool extract_tar(std::string const& arFileName, bool cmSystemTools::ExtractTar(std::string const& arFileName, std::vector const& files, cmTarExtractTimestamps extractTimestamps, - bool verbose) + std::string const& encoding, bool verbose) { #if !defined(CMAKE_BOOTSTRAP) - return extract_tar(arFileName, files, verbose, extractTimestamps, true); + return extract_tar(arFileName, files, encoding, verbose, extractTimestamps, + true); #else (void)arFileName; (void)files; (void)extractTimestamps; + (void)encoding; (void)verbose; return false; #endif @@ -2764,14 +2775,15 @@ bool cmSystemTools::ExtractTar(std::string const& arFileName, bool cmSystemTools::ListTar(std::string const& arFileName, std::vector const& files, - bool verbose) + std::string const& encoding, bool verbose) { #if !defined(CMAKE_BOOTSTRAP) - return extract_tar(arFileName, files, verbose, cmTarExtractTimestamps::Yes, - false); + return extract_tar(arFileName, files, encoding, verbose, + cmTarExtractTimestamps::Yes, false); #else (void)arFileName; (void)files; + (void)encoding; (void)verbose; return false; #endif diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index c28a0b2516..2813e4331b 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -562,18 +562,20 @@ public: }; static bool ListTar(std::string const& arFileName, - std::vector const& files, bool verbose); + std::vector const& files, + std::string const& encoding, bool verbose); static bool CreateTar(std::string const& arFileName, std::vector const& files, std::string const& workingDirectory, - cmTarCompression compressType, bool verbose, + cmTarCompression compressType, + std::string const& encoding, bool verbose, std::string const& mtime = std::string(), std::string const& format = std::string(), int compressionLevel = 0, int numThreads = 1); static bool ExtractTar(std::string const& arFileName, std::vector const& files, cmTarExtractTimestamps extractTimestamps, - bool verbose); + std::string const& encoding, bool verbose); /** Random number generation. */ static unsigned int RandomSeed(); diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 105c4d7b9d..ef142fb8a6 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1920,6 +1920,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector const& args, cmSystemTools::TarCompressAuto; int nCompress = 0; bool doing_options = true; + std::string encoding = "OEM"; for (auto const& arg : cmMakeRange(args).advance(4)) { if (doing_options && cmHasLiteralPrefix(arg, "--")) { if (arg == "--") { @@ -1957,6 +1958,13 @@ int cmcmd::ExecuteCMakeCommand(std::vector const& args, } numThreads = static_cast(numThreadsLong); + } else if (cmHasLiteralPrefix(arg, "--cmake-tar-encoding=")) { + encoding = arg.substr(21); + if (encoding.empty()) { + cmSystemTools::Error( + "Encoding value is empty - it must be filled if passed"); + return 1; + } } else if (cmHasLiteralPrefix(arg, "--cmake-tar-compression-level=")) { std::string const& compressionLevelStr = arg.substr(30); @@ -2106,7 +2114,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector const& args, } if (action == cmSystemTools::TarActionList) { - if (!cmSystemTools::ListTar(outFile, files, verbose)) { + if (!cmSystemTools::ListTar(outFile, files, encoding, verbose)) { cmSystemTools::Error("Problem listing tar: " + outFile); return 1; } @@ -2114,15 +2122,15 @@ int cmcmd::ExecuteCMakeCommand(std::vector const& args, if (files.empty()) { std::cerr << "tar: No files or directories specified\n"; } - if (!cmSystemTools::CreateTar(outFile, files, {}, compress, verbose, - mtime, format, compressionLevel, + if (!cmSystemTools::CreateTar(outFile, files, {}, compress, encoding, + verbose, mtime, format, compressionLevel, numThreads)) { cmSystemTools::Error(cmStrCat("Problem creating tar:\n ", outFile)); return 1; } } else if (action == cmSystemTools::TarActionExtract) { if (!cmSystemTools::ExtractTar(outFile, files, extractTimestamps, - verbose)) { + encoding, verbose)) { cmSystemTools::Error( cmStrCat("Problem extracting tar:\n ", outFile)); return 1; diff --git a/Tests/Fuzzing/cmArchiveExtractFuzzer.cxx b/Tests/Fuzzing/cmArchiveExtractFuzzer.cxx index a4f66b6617..4901d6d534 100644 --- a/Tests/Fuzzing/cmArchiveExtractFuzzer.cxx +++ b/Tests/Fuzzing/cmArchiveExtractFuzzer.cxx @@ -87,7 +87,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size) // Extract without verbose, with timestamps bool result1 = cmSystemTools::ExtractTar( - archiveFile, files, cmSystemTools::cmTarExtractTimestamps::Yes, false); + archiveFile, files, cmSystemTools::cmTarExtractTimestamps::Yes, "OEM", + false); (void)result1; // Restore directory BEFORE removing (can't remove cwd) @@ -102,7 +103,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size) // Extract with verbose, without timestamps files.clear(); bool result2 = cmSystemTools::ExtractTar( - archiveFile, files, cmSystemTools::cmTarExtractTimestamps::No, true); + archiveFile, files, cmSystemTools::cmTarExtractTimestamps::No, "OEM", + true); (void)result2; // Restore directory diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 6e1e596aeb..fe8bac7eba 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -1100,6 +1100,9 @@ add_RunCMake_test(CommandLine -DLLVM_RC=$ -DCMAKE_SY if(CMake_TEST_LibArchive_VERSION) list(APPEND CommandLineTar_ARGS -DCMake_TEST_LibArchive_VERSION=${CMake_TEST_LibArchive_VERSION}) endif() +if(DEFINED CMake_TEST_LOCALE_CHARSET) + list(APPEND CommandLineTar_ARGS -DCMake_TEST_LOCALE_CHARSET=${CMake_TEST_LOCALE_CHARSET}) +endif() list(APPEND CommandLineTar_ARGS -DPython_EXECUTABLE=${Python_EXECUTABLE}) add_RunCMake_test(CommandLineTar) diff --git a/Tests/RunCMake/CPack/TAR/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/TAR/packaging_COMPONENT_default.cmake index 81a5035a3d..a6801f322f 100644 --- a/Tests/RunCMake/CPack/TAR/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/TAR/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_ARCHIVE_ENCODING "OEM") diff --git a/Tests/RunCMake/CPack/ZIP/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/ZIP/packaging_COMPONENT_default.cmake index 81a5035a3d..a6801f322f 100644 --- a/Tests/RunCMake/CPack/ZIP/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/ZIP/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_ARCHIVE_ENCODING "OEM") diff --git a/Tests/RunCMake/CPack/ZIP_DEFLATE/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/ZIP_DEFLATE/packaging_COMPONENT_default.cmake index 2a5727999c..e1f8e705a0 100644 --- a/Tests/RunCMake/CPack/ZIP_DEFLATE/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/ZIP_DEFLATE/packaging_COMPONENT_default.cmake @@ -1,2 +1,3 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") set(CPACK_ARCHIVE_COMPRESSION_LEVEL 4) +set(CPACK_ARCHIVE_ENCODING "UTF-8") diff --git a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake index e2b0ca72f3..01c2f7e3e6 100644 --- a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake @@ -119,6 +119,34 @@ run_cmake(compression-method-lzma) run_cmake(compression-method-zstd) run_cmake(compression-method-ppmd) +# Encoding tests. These rely on UTF-8 encoding of our test sources. +if(NOT DEFINED CMake_TEST_LOCALE_CHARSET) + cmake_host_system_information(RESULT CMake_TEST_LOCALE_CHARSET QUERY LOCALE_CHARSET) + message(STATUS "Detected LOCALE_CHARSET '${CMake_TEST_LOCALE_CHARSET}'") +endif() +if(CMake_TEST_LOCALE_CHARSET STREQUAL "UTF-8") + if(CMAKE_HOST_WIN32) + # The OEM encoding cannot represent our UTF-8 test paths. + run_cmake(encoding-oem-gnutar-fails) + run_cmake(encoding-oem-zip-fails) + else() + run_cmake(encoding-oem-gnutar) + run_cmake(encoding-oem-zip) + endif() + + run_cmake(encoding-oem-7zip) + run_cmake(encoding-oem-pax) + run_cmake(encoding-oem-paxr) + + run_cmake(encoding-utf-8-7zip) + run_cmake(encoding-utf-8-gnutar) + run_cmake(encoding-utf-8-pax) + run_cmake(encoding-utf-8-paxr) + run_cmake(encoding-utf-8-zip) +else() + message(STATUS "encoding-* - SKIPPED due to non-UTF-8 locale") +endif() + # Extracting only selected files or directories run_cmake(zip-filtered) diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-7zip.cmake b/Tests/RunCMake/CommandLineTar/encoding-oem-7zip.cmake new file mode 100644 index 0000000000..722ca8e7de --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-7zip.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.7z") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=7zip --cmake-tar-encoding=OEM) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=OEM) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("377abcaf271c" LIMIT 6 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails-result.txt b/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails-stderr.txt b/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails-stderr.txt new file mode 100644 index 0000000000..ba1bc13727 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error: archive_write_header: Can't translate [Pp]athname( '[^']*\.txt')? to [^ +]* +CMake Error: Problem creating tar: +[^ +]*/bad\.tar +CMake Error at roundtrip\.cmake:[0-9]+ \(message\): diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails.cmake b/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails.cmake new file mode 100644 index 0000000000..10ae837666 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar-fails.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "bad.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=gnutar --cmake-tar-encoding=OEM) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=OEM) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172202000" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar.cmake b/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar.cmake new file mode 100644 index 0000000000..93bcd1c8db --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-gnutar.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=gnutar --cmake-tar-encoding=OEM) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=OEM) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172202000" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-pax.cmake b/Tests/RunCMake/CommandLineTar/encoding-oem-pax.cmake new file mode 100644 index 0000000000..603ef66121 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-pax.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=pax --cmake-tar-encoding=OEM) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=OEM) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-paxr.cmake b/Tests/RunCMake/CommandLineTar/encoding-oem-paxr.cmake new file mode 100644 index 0000000000..12b61976aa --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-paxr.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=paxr --cmake-tar-encoding=OEM) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=OEM) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails-result.txt b/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails-stderr.txt b/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails-stderr.txt new file mode 100644 index 0000000000..5f0acc3a68 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error: archive_write_header: Can't translate [Pp]athname( '[^']*\.txt')? to [^ +]* +CMake Error: Problem creating tar: +[^ +]*/bad\.zip +CMake Error at roundtrip\.cmake:[0-9]+ \(message\): diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails.cmake b/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails.cmake new file mode 100644 index 0000000000..17e3da30b1 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-zip-fails.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "bad.zip") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=zip --cmake-tar-encoding=OEM) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=OEM) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("504b0304" LIMIT 4 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-oem-zip.cmake b/Tests/RunCMake/CommandLineTar/encoding-oem-zip.cmake new file mode 100644 index 0000000000..5112770580 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-oem-zip.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.zip") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=zip --cmake-tar-encoding=OEM) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=OEM) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("504b0304" LIMIT 4 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-utf-8-7zip.cmake b/Tests/RunCMake/CommandLineTar/encoding-utf-8-7zip.cmake new file mode 100644 index 0000000000..cdecb90955 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-utf-8-7zip.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.7z") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=7zip --cmake-tar-encoding=UTF-8) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=UTF-8) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("377abcaf271c" LIMIT 6 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-utf-8-gnutar.cmake b/Tests/RunCMake/CommandLineTar/encoding-utf-8-gnutar.cmake new file mode 100644 index 0000000000..e74f87f8f0 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-utf-8-gnutar.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=gnutar --cmake-tar-encoding=UTF-8) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=UTF-8) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172202000" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-utf-8-pax.cmake b/Tests/RunCMake/CommandLineTar/encoding-utf-8-pax.cmake new file mode 100644 index 0000000000..10b2342c6b --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-utf-8-pax.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=pax --cmake-tar-encoding=UTF-8) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=UTF-8) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-utf-8-paxr.cmake b/Tests/RunCMake/CommandLineTar/encoding-utf-8-paxr.cmake new file mode 100644 index 0000000000..5adc9dc219 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-utf-8-paxr.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=paxr --cmake-tar-encoding=UTF-8) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=UTF-8) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/encoding-utf-8-zip.cmake b/Tests/RunCMake/CommandLineTar/encoding-utf-8-zip.cmake new file mode 100644 index 0000000000..fded11f969 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/encoding-utf-8-zip.cmake @@ -0,0 +1,12 @@ +set(OUTPUT_NAME "test.zip") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=zip --cmake-tar-encoding=UTF-8) +include(${CMAKE_CURRENT_LIST_DIR}/utf-8-paths.cmake) + +set(DECOMPRESSION_FLAGS xvf) +set(DECOMPRESSION_OPTIONS --cmake-tar-encoding=UTF-8) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("504b0304" LIMIT 4 HEX) diff --git a/Tests/RunCMake/CommandLineTar/roundtrip.cmake b/Tests/RunCMake/CommandLineTar/roundtrip.cmake index a93c783bbc..2ecbc16341 100644 --- a/Tests/RunCMake/CommandLineTar/roundtrip.cmake +++ b/Tests/RunCMake/CommandLineTar/roundtrip.cmake @@ -31,6 +31,7 @@ set(CHECK_FILES "d_4/f1.txt" "d-4/f1.txt" "My Special Directory/f1.txt" + ${COMPRESSION_ADDITIONAL_FILE_NAMES} ) foreach(file ${CHECK_FILES}) diff --git a/Tests/RunCMake/CommandLineTar/utf-8-paths.cmake b/Tests/RunCMake/CommandLineTar/utf-8-paths.cmake new file mode 100644 index 0000000000..af85ffac87 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/utf-8-paths.cmake @@ -0,0 +1,10 @@ +list(APPEND COMPRESSION_ADDITIONAL_FILE_NAMES + "arabic-نَسِيج.txt" + "armenian-Բարեւ ձեզ.txt" + "chinese-质地.txt" + "cyrillic-привет.txt" + "greek-Γεια.txt" + "hungarian-hűtő.txt" + "japanese-テクスチャ.txt" + "korean-조직.txt" +) diff --git a/Tests/RunCMake/File_Archive/roundtrip.cmake b/Tests/RunCMake/File_Archive/roundtrip.cmake index 99b87af5cb..5b70b61af2 100644 --- a/Tests/RunCMake/File_Archive/roundtrip.cmake +++ b/Tests/RunCMake/File_Archive/roundtrip.cmake @@ -58,18 +58,25 @@ foreach(file ${CHECK_FILES}) set(output ${FULL_DECOMPRESS_DIR}/${CUSTOM_OUTPUT_DIRECTORY}/${COMPRESS_DIR}/${file}) if(NOT EXISTS ${input}) - message(SEND_ERROR "Cannot find input file ${input}") + message(SEND_ERROR "Cannot find input file:\n \"${output}\"") endif() if(NOT EXISTS ${output}) - message(SEND_ERROR "Cannot find output file ${output}") + message(SEND_ERROR "Cannot find output file:\n \"${output}\"") endif() file(MD5 ${input} input_md5) file(MD5 ${output} output_md5) if(NOT input_md5 STREQUAL output_md5) - message(SEND_ERROR "Files \"${input}\" and \"${output}\" are different") + message(SEND_ERROR + "Files:\n" + " \"${input}\"\n" + "and\n" + " \"${output}\"\n" + "are different" + ) + endif() endforeach() @@ -77,7 +84,7 @@ foreach(file ${NOT_EXISTING_FILES_CHECK}) set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file}) if(EXISTS ${output}) - message(SEND_ERROR "File ${output} exists but it shouldn't") + message(SEND_ERROR "File exists but it shouldn't:\n \"${output}\"") endif() endforeach()