# HG changeset patch # User Sebastien Jodogne # Date 1771605658 -3600 # Node ID 3f857772f59ad4b2f313db938e869c37df59f9a1 # Parent 4f5811d75978fc2bd9a84436d1ef0be1e88a9057 preparing for utf-8 in zip diff -r 4f5811d75978 -r 3f857772f59a OrthancFramework/Sources/Compression/ZipWriter.cpp --- a/OrthancFramework/Sources/Compression/ZipWriter.cpp Fri Feb 20 16:55:34 2026 +0100 +++ b/OrthancFramework/Sources/Compression/ZipWriter.cpp Fri Feb 20 17:40:58 2026 +0100 @@ -38,6 +38,7 @@ #include "../Logging.h" #include "../OrthancException.h" #include "../SystemToolbox.h" +#include "../Toolbox.h" static void PrepareFileInfo(zip_fileinfo& zfi) @@ -607,6 +608,30 @@ { Open(); + std::string utf8; + +#if 0 + if (Toolbox::IsValidUtf8(filename)) + { + /** + * Starting with minizip 1.3.2 (released on 17 Feb 2026), bit 11 + * of the ZIP header flags is appropriately set if the filename + * is encoded using UTF-8. This enables compatibility with UTF-8. + * https://zlib.net/ChangeLog.txt + * https://discourse.orthanc-server.org/t/seriesdescription-characters-and-removed-during-oe2-zip-export/6397 + **/ + utf8 = filename; + } + else + { + // Fallback if the filename is not encoded using valid UTF-8 + utf8 = Toolbox::ConvertToAscii(filename); + } +#else + // This was the code used in Orthanc <= 1.12.10 + utf8 = Toolbox::ConvertToAscii(filename); +#endif + zip_fileinfo zfi; PrepareFileInfo(zfi); @@ -614,7 +639,7 @@ if (isZip64_) { - result = zipOpenNewFileInZip64(pimpl_->file_, filename.c_str(), + result = zipOpenNewFileInZip64(pimpl_->file_, utf8.c_str(), &zfi, NULL, 0, NULL, 0, @@ -624,7 +649,7 @@ } else { - result = zipOpenNewFileInZip(pimpl_->file_, filename.c_str(), + result = zipOpenNewFileInZip(pimpl_->file_, utf8.c_str(), &zfi, NULL, 0, NULL, 0, diff -r 4f5811d75978 -r 3f857772f59a OrthancFramework/UnitTestsSources/ZipTests.cpp --- a/OrthancFramework/UnitTestsSources/ZipTests.cpp Fri Feb 20 16:55:34 2026 +0100 +++ b/OrthancFramework/UnitTestsSources/ZipTests.cpp Fri Feb 20 17:40:58 2026 +0100 @@ -36,6 +36,8 @@ #include "../Sources/TemporaryFile.h" #include "../Sources/Toolbox.h" +#include "../Resources/CodeGeneration/EncodingTests.h" + using namespace Orthanc; @@ -413,3 +415,48 @@ ASSERT_EQ(0u, buffer.GetPosition()); } } + + +TEST(HierarchicalZipWriter, DISABLED_Utf8) +{ + (void) toUpperResult; + (void) toUpperSource; + (void) testEncodingsExpected; + + static const std::string path = "UnitTestsResults/hello-utf8.zip"; + + { + Orthanc::ZipWriter w; + w.SetOutputPath(path); + + for (unsigned int i = 0; i < testEncodingsCount; i++) + { + std::string source(testEncodingsEncoded[i]); + std::string s = Toolbox::ConvertToUtf8(source, testEncodings[i], false, false); + ASSERT_TRUE(Orthanc::Toolbox::IsValidUtf8(s)); + printf("[%s]\n", s.c_str()); + w.OpenFile(s); + w.Write("Hello"); + } + } + + { + std::unique_ptr reader(ZipReader::CreateFromFile(path)); + + ASSERT_EQ(testEncodingsCount, reader->GetFilesCount()); + + std::set files; + std::string filename, content; + while (reader->ReadNextFile(filename, content)) + { + files.insert(filename); + } + + for (unsigned int i = 0; i < testEncodingsCount; i++) + { + std::string source(testEncodingsEncoded[i]); + std::string s = Toolbox::ConvertToUtf8(source, testEncodings[i], false, false); + ASSERT_TRUE(files.find(s) != files.end()); + } + } +} diff -r 4f5811d75978 -r 3f857772f59a OrthancServer/Sources/ServerJobs/ArchiveJob.cpp --- a/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp Fri Feb 20 16:55:34 2026 +0100 +++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp Fri Feb 20 17:40:58 2026 +0100 @@ -1020,7 +1020,7 @@ } } - path = Toolbox::StripSpaces(Toolbox::ConvertToAscii(path)); + path = Toolbox::StripSpaces(path); if (path.empty() || (static_cast(boost::count(path, '^')) == path.size())) // this happens with non ASCII patient names: only the '^' remains and this is not a valid zip folder name