diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp --- a/CPP/7zip/Archive/Zip/ZipIn.cpp 2016-05-20 16:20:03.000000000 +0800 +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp 2017-01-30 14:51:29.000000000 +0800 @@ -2,6 +2,9 @@ #include "StdAfx.h" +#include <iconv.h> +#include <natspec.h> + // #include <stdio.h> #include "../../../Common/DynamicBuffer.h" @@ -16,6 +19,8 @@ #include "ZipIn.h" +#include "myPrivate.h" // global_use_utf16_conversion + #define Get16(p) GetUi16(p) #define Get32(p) GetUi32(p) #define Get64(p) GetUi64(p) @@ -604,6 +609,19 @@ } +void CInArchive::RecodeFileName(CItem &item) { + if (item.IsUtf8()) return; + + /* Convert filename from archive charset to current locale's charset */ + char *p = natspec_convert(item.Name.Ptr(), NULL, archive_oem_charset, 0); + if (p) { + item.Name = p; + item.SetUtf8(true); + USING_UTF8 = true; + free(p); + } +} + bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extraBlock, UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) { @@ -745,6 +763,7 @@ HeadersWarning = true; } + RecodeFileName(item); return item.LocalFullHeaderSize <= ((UInt32)1 << 16); } @@ -1017,6 +1036,7 @@ G32(34, item.ExternalAttrib); G32(38, item.LocalHeaderPos); ReadFileName(nameSize, item.Name); + RecodeFileName(item); if (extraSize > 0) ReadExtra(extraSize, item.CentralExtra, item.Size, item.PackSize, item.LocalHeaderPos, item.Disk); @@ -2126,6 +2146,9 @@ StartStream = stream; Callback = callback; + /* Guess archive filename charset */ + archive_oem_charset = natspec_get_charset_by_locale(NATSPEC_DOSCS, ""); + bool volWasRequested = false; if (callback diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h --- a/CPP/7zip/Archive/Zip/ZipIn.h 2016-05-19 01:30:59.000000000 +0800 +++ b/CPP/7zip/Archive/Zip/ZipIn.h 2017-01-30 14:50:14.000000000 +0800 @@ -349,6 +349,9 @@ return true; } + + const char *archive_oem_charset; + void RecodeFileName(CItem &item); }; }} diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp --- a/CPP/7zip/Archive/Zip/ZipItem.cpp 2016-02-02 00:50:10.000000000 +0800 +++ b/CPP/7zip/Archive/Zip/ZipItem.cpp 2017-01-30 14:50:14.000000000 +0800 @@ -15,6 +15,8 @@ namespace NArchive { namespace NZip { +bool USING_UTF8 = true; + using namespace NFileHeader; bool CExtraSubBlock::ExtractNtfsTime(unsigned index, FILETIME &ft) const diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h --- a/CPP/7zip/Archive/Zip/ZipItem.h 2016-05-19 01:30:59.000000000 +0800 +++ b/CPP/7zip/Archive/Zip/ZipItem.h 2017-01-30 14:50:14.000000000 +0800 @@ -14,6 +14,8 @@ namespace NArchive { namespace NZip { +extern bool USING_UTF8; + struct CVersion { Byte Version; diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp --- a/CPP/7zip/Archive/Zip/ZipOut.cpp 2014-12-21 20:44:02.000000000 +0800 +++ b/CPP/7zip/Archive/Zip/ZipOut.cpp 2017-01-30 14:50:14.000000000 +0800 @@ -2,10 +2,15 @@ #include "StdAfx.h" +#include <iconv.h> +#include <natspec.h> + #include "../../Common/OffsetStream.h" #include "ZipOut.h" +#include "myPrivate.h" // global_use_utf16_conversion + namespace NArchive { namespace NZip { @@ -18,9 +23,24 @@ m_OutBuffer.SetStream(outStream); m_OutBuffer.Init(); + /* Guess archive filename charset */ + archive_oem_charset = natspec_get_charset_by_locale(NATSPEC_DOSCS, ""); + return m_Stream->Seek(0, STREAM_SEEK_CUR, &m_Base); } +void COutArchive::RecodeFileName(CItem &item) { + if (USING_UTF8) return; + + /* Convert filename from current locale charset to archive charset. */ + char *p = natspec_convert(item.Name.Ptr(), archive_oem_charset, NULL, 0); + if (p) { + item.Name = p; + item.SetUtf8(false); + free(p); + } +} + void COutArchive::MoveCurPos(UInt64 distanceToMove) { m_CurPos += distanceToMove; // test overflow diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h --- a/CPP/7zip/Archive/Zip/ZipOut.h 2015-06-19 18:52:06.000000000 +0800 +++ b/CPP/7zip/Archive/Zip/ZipOut.h 2017-01-30 14:50:14.000000000 +0800 @@ -81,6 +81,9 @@ void CreateStreamForCompressing(IOutStream **outStream); void CreateStreamForCopying(ISequentialOutStream **outStream); + + const char *archive_oem_charset; + void RecodeFileName(CItem &item); }; }} diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp --- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2016-05-20 16:35:36.000000000 +0800 +++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2017-01-30 14:50:14.000000000 +0800 @@ -79,6 +79,8 @@ else isDir = item.IsDir(); + archive.RecodeFileName(item); + item.LocalHeaderPos = archive.GetCurPos(); item.MadeByVersion.HostOS = kMadeByHostOS; item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion; @@ -364,6 +366,7 @@ item.Ntfs_ATime = ui.Ntfs_ATime; item.Ntfs_CTime = ui.Ntfs_CTime; item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; + archive.RecodeFileName(item); item.CentralExtra.RemoveUnknownSubBlocks(); item.LocalExtra.RemoveUnknownSubBlocks(); @@ -383,6 +386,8 @@ if (!packStream) return E_NOTIMPL; + archive.RecodeFileName(item); + // set new header position item.LocalHeaderPos = archive.GetCurPos(); diff -Naur -x '.*' a/makefile.linux_amd64_asm b/makefile.linux_amd64_asm --- a/makefile.linux_amd64_asm 2015-09-19 17:49:28.000000000 +0800 +++ b/makefile.linux_amd64_asm 2017-01-30 14:50:14.000000000 +0800 @@ -19,7 +19,7 @@ PRE_COMPILED_HEADER=StdAfx.h.gch -LOCAL_LIBS=-lpthread +LOCAL_LIBS=-lpthread -lnatspec LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl CPU=x64 diff -Naur -x '.*' a/makefile.linux_any_cpu_gcc_4.X b/makefile.linux_any_cpu_gcc_4.X --- a/makefile.linux_any_cpu_gcc_4.X 2015-09-14 02:17:48.000000000 +0800 +++ b/makefile.linux_any_cpu_gcc_4.X 2017-01-30 14:50:14.000000000 +0800 @@ -19,7 +19,7 @@ PRE_COMPILED_HEADER=StdAfx.h.gch -LOCAL_LIBS=-lpthread +LOCAL_LIBS=-lpthread -lnatspec LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl OBJ_CRC32=$(OBJ_CRC32_C) diff -Naur -x '.*' a/makefile.linux_x86_asm_gcc_4.X b/makefile.linux_x86_asm_gcc_4.X --- a/makefile.linux_x86_asm_gcc_4.X 2015-09-19 17:49:28.000000000 +0800 +++ b/makefile.linux_x86_asm_gcc_4.X 2017-01-30 14:50:14.000000000 +0800 @@ -22,7 +22,7 @@ PRE_COMPILED_HEADER=StdAfx.h.gch -LOCAL_LIBS=-lpthread +LOCAL_LIBS=-lpthread -lnatspec LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl CPU=x86 diff -Naur -x '.*' a/makefile.macosx_gcc_64bits b/makefile.macosx_gcc_64bits --- a/makefile.macosx_gcc_64bits 2015-01-12 00:34:26.000000000 +0800 +++ b/makefile.macosx_gcc_64bits 2017-01-30 14:54:27.000000000 +0800 @@ -13,7 +13,7 @@ CC=cc LINK_SHARED=-bundle -LOCAL_LIBS=-framework CoreFoundation +LOCAL_LIBS=-framework CoreFoundation -lnatspec -liconv LOCAL_LIBS_DLL=$(LOCAL_LIBS) OBJ_CRC32=$(OBJ_CRC32_C) diff -Naur -x '.*' a/makefile.macosx_llvm_64bits b/makefile.macosx_llvm_64bits --- a/makefile.macosx_llvm_64bits 2015-06-13 22:40:46.000000000 +0800 +++ b/makefile.macosx_llvm_64bits 2017-01-30 14:54:29.000000000 +0800 @@ -19,7 +19,7 @@ LINK_SHARED=-bundle -LOCAL_LIBS=-framework CoreFoundation +LOCAL_LIBS=-framework CoreFoundation -lnatspec -liconv LOCAL_LIBS_DLL=$(LOCAL_LIBS) OBJ_CRC32=$(OBJ_CRC32_C)